@jsenv/navi 0.26.2 → 0.26.4

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.
@@ -3,7 +3,7 @@ import { isValidElement, createContext, h, options, toChildArray, render, cloneE
3
3
  import { useErrorBoundary, useLayoutEffect, useEffect, useContext, useMemo, useRef, useState, useCallback, useImperativeHandle, useId } from "preact/hooks";
4
4
  import { jsxs, jsx, Fragment } from "preact/jsx-runtime";
5
5
  import { signal, effect, computed, batch, useSignal } from "@preact/signals";
6
- import { createIterableWeakSet, mergeOneStyle, stringifyStyle, createPubSub, mergeTwoStyles, normalizeStyles, createGroupTransitionController, getElementSignature, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, findBefore, findAfter, createValueEffect, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, allowWheelThrough, resolveCSSColor, createStyleController, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, resolveCSSSize, canInterceptKeys, activeElementSignal, hasCSSSizeUnit, resolveOklchLightness, contrastColor, initFocusGroup, elementIsFocusable, scrollIntoViewScoped, findFocusable, trapScrollInside, trapFocusInside, dragAfterThreshold, getScrollContainer, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
6
+ import { createIterableWeakSet, getElementSignature, mergeOneStyle, stringifyStyle, createPubSub, mergeTwoStyles, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, findBefore, findAfter, createValueEffect, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, allowWheelThrough, resolveCSSColor, createStyleController, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, resolveCSSSize, canInterceptKeys, activeElementSignal, hasCSSSizeUnit, resolveOklchLightness, contrastColor, initFocusGroup, elementIsFocusable, scrollIntoViewScoped, findFocusable, trapScrollInside, trapFocusInside, dragAfterThreshold, getScrollContainer, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
7
7
  export { contrastColor } from "@jsenv/dom";
8
8
  import { prefixFirstAndIndentRemainingLines } from "@jsenv/humanize";
9
9
  import { createValidity } from "@jsenv/validity";
@@ -2450,7 +2450,7 @@ const useRunOnMount = (action, Component) => {
2450
2450
 
2451
2451
  const DebugFocusContext = createContext(false);
2452
2452
  const DebugScrollContext = createContext(false);
2453
- const DebugPopoverContext = createContext(false);
2453
+ const DebugPopupContext = createContext(false);
2454
2454
  const debugNoop = () => {};
2455
2455
  const useDebugFocus = () => {
2456
2456
  const debug = useContext(DebugFocusContext);
@@ -2460,8 +2460,8 @@ const useDebugScroll = () => {
2460
2460
  const debug = useContext(DebugScrollContext);
2461
2461
  return debug || debugNoop;
2462
2462
  };
2463
- const useDebugPopover = () => {
2464
- const debug = useContext(DebugPopoverContext);
2463
+ const useDebugPopup = () => {
2464
+ const debug = useContext(DebugPopupContext);
2465
2465
  return debug || debugNoop;
2466
2466
  };
2467
2467
 
@@ -2471,14 +2471,14 @@ const useDebugPopover = () => {
2471
2471
  * Props:
2472
2472
  * debugFocus — log focus moves (autoFocus, restoring previous focus, etc.)
2473
2473
  * debugScroll — log virtual scroll window updates and scroll-to-item calls
2474
- * debugPopover — log popover open/close/positioning decisions
2474
+ * debugPopup — log popover open/close/positioning decisions
2475
2475
  *
2476
2476
  * Pass a boolean `true` to use `console.debug`, or pass a custom function.
2477
2477
  */
2478
2478
  const NaviDebug = ({
2479
2479
  debugFocus,
2480
2480
  debugScroll,
2481
- debugPopover,
2481
+ debugPopup,
2482
2482
  children
2483
2483
  }) => {
2484
2484
  if (debugFocus === true) {
@@ -2487,20 +2487,23 @@ const NaviDebug = ({
2487
2487
  if (debugScroll === true) {
2488
2488
  debugScroll = console.debug;
2489
2489
  }
2490
- if (debugPopover === true) {
2491
- debugPopover = console.debug;
2490
+ if (debugPopup === true) {
2491
+ debugPopup = console.debug;
2492
2492
  }
2493
2493
  return jsx(DebugFocusContext.Provider, {
2494
2494
  value: debugFocus,
2495
2495
  children: jsx(DebugScrollContext.Provider, {
2496
2496
  value: debugScroll,
2497
- children: jsx(DebugPopoverContext.Provider, {
2498
- value: debugPopover,
2497
+ children: jsx(DebugPopupContext.Provider, {
2498
+ value: debugPopup,
2499
2499
  children: children
2500
2500
  })
2501
2501
  })
2502
2502
  });
2503
2503
  };
2504
+ const formatEventSideEffect = (e, sideEffect) => {
2505
+ return `"${e.type}" on ${getElementSignature(e.target)} -> ${sideEffect}`;
2506
+ };
2504
2507
 
2505
2508
  const addIntoArray = (array, ...valuesToAdd) => {
2506
2509
  if (valuesToAdd.length === 1) {
@@ -6650,14 +6653,7 @@ const CONTENT_PROPS = {
6650
6653
  };
6651
6654
  },
6652
6655
  spacing: (value, { boxFlow }) => {
6653
- if (
6654
- boxFlow === "flex-x" ||
6655
- boxFlow === "flex-y" ||
6656
- boxFlow === "inline-flex-x" ||
6657
- boxFlow === "inline-flex-y" ||
6658
- boxFlow === "grid" ||
6659
- boxFlow === "inline-grid"
6660
- ) {
6656
+ if (isSpacingHandledByFlow(boxFlow)) {
6661
6657
  return {
6662
6658
  gap: resolveSpacingSize(value, "gap"),
6663
6659
  };
@@ -6691,6 +6687,18 @@ const CONTENT_PROPS = {
6691
6687
  return undefined;
6692
6688
  },
6693
6689
  };
6690
+ const flowSpacingHandlerSet = new Set([
6691
+ "flex-x",
6692
+ "flex-y",
6693
+ "inline-flex-x",
6694
+ "inline-flex-y",
6695
+ "grid",
6696
+ "inline-grid",
6697
+ ]);
6698
+ const isSpacingHandledByFlow = (boxFlow) => {
6699
+ return flowSpacingHandlerSet.has(boxFlow);
6700
+ };
6701
+
6694
6702
  const All_PROPS = {
6695
6703
  ...FLOW_PROPS,
6696
6704
  ...OUTER_SPACING_PROPS,
@@ -7642,6 +7650,11 @@ definePseudoClass(":active", {
7642
7650
  if (isControlledByFocusedElement(el)) {
7643
7651
  return true;
7644
7652
  }
7653
+ if (el.contains(document.activeElement)) {
7654
+ // for some reason :focus-within sometimes is false while focus is within...
7655
+ // (popover with chrome for some reason)
7656
+ return true;
7657
+ }
7645
7658
  return false;
7646
7659
  },
7647
7660
  });
@@ -8286,6 +8299,8 @@ const Box = props => {
8286
8299
  const ref = props.ref || defaultRef;
8287
8300
  const TagName = as;
8288
8301
  const defaultDisplay = getDefaultDisplay(TagName);
8302
+ // Read the parent flow early so we can use it when display="inherit" is requested.
8303
+ const parentBoxFlow = useContext(BoxFlowContext);
8289
8304
  let {
8290
8305
  inline,
8291
8306
  block,
@@ -8353,6 +8368,12 @@ const Box = props => {
8353
8368
  } else {
8354
8369
  boxFlow = defaultDisplay;
8355
8370
  }
8371
+ // When display="inherit" is passed, adopt the parent's flow instead of computing one.
8372
+ // This lets a child Box mirror its parent's flex/grid/block layout without repeating
8373
+ // the same layout props, and is used e.g. by Button's inner content element.
8374
+ if (rest.display === "inherit") {
8375
+ boxFlow = parentBoxFlow;
8376
+ }
8356
8377
  const boxFlowIsDefault = boxFlow === defaultDisplay;
8357
8378
  const remainingPropKeySet = new Set(Object.keys(rest));
8358
8379
  // some props not destructured but that are neither
@@ -8362,7 +8383,6 @@ const Box = props => {
8362
8383
  const selfForwardedProps = {};
8363
8384
  const childForwardedProps = {};
8364
8385
  {
8365
- const parentBoxFlow = useContext(BoxFlowContext);
8366
8386
  const styleDeps = [
8367
8387
  // Layout and alignment props
8368
8388
  parentBoxFlow, boxFlow,
@@ -16587,14 +16607,22 @@ const openCallout = (message, {
16587
16607
  }
16588
16608
  allowWheelThrough(calloutElement, anchorElement);
16589
16609
  anchorElement.setAttribute("data-callout", calloutId);
16590
- dispatchCalloutCustomElement(anchorElement, new CustomEvent("navi_callout_open", {
16591
- bubbles: true
16592
- }));
16593
16610
  addTeardown(() => {
16594
16611
  anchorElement.removeAttribute("data-callout");
16595
- dispatchCalloutCustomElement(anchorElement, new CustomEvent("navi_callout_close", {
16596
- bubbles: true
16597
- }));
16612
+ });
16613
+ const visualElement = (() => {
16614
+ const visualSelector = anchorElement.getAttribute("data-visual-selector");
16615
+ if (visualSelector) {
16616
+ const visualElement = anchorElement.querySelector(visualSelector);
16617
+ if (visualElement) {
16618
+ return visualElement;
16619
+ }
16620
+ }
16621
+ return anchorElement;
16622
+ })();
16623
+ dispatchPublicCustomEvent(visualElement, "navi_callout_open");
16624
+ addTeardown(() => {
16625
+ dispatchPublicCustomEvent(visualElement, "navi_callout_close");
16598
16626
  });
16599
16627
  addStatusEffect(status => {
16600
16628
  if (!status) {
@@ -16857,7 +16885,7 @@ const stickCalloutToAnchor = (calloutElement, anchorElement) => {
16857
16885
  }) => {
16858
16886
  const calloutElementClone = cloneCalloutToMeasureNaturalSize(calloutElement);
16859
16887
  const {
16860
- position,
16888
+ positionY,
16861
16889
  left: calloutLeft,
16862
16890
  top: calloutTop,
16863
16891
  width: calloutWidth,
@@ -16865,20 +16893,19 @@ const stickCalloutToAnchor = (calloutElement, anchorElement) => {
16865
16893
  spaceAbove,
16866
16894
  spaceBelow
16867
16895
  } = pickPositionRelativeTo(calloutElementClone, anchorElement, {
16868
- alignToViewportEdgeWhenTargetNearEdge: 20,
16869
- // when fully to the left, the border color is collé to the browser window making it hard to see
16896
+ alignToViewportEdgeWhenAnchorNearEdge: 20,
16870
16897
  minLeft: 1,
16871
- // Check for preferred and forced position from anchor element
16872
- positionTry: anchorElement.getAttribute("data-callout-position-try") || "bottom",
16873
- position: anchorElement.getAttribute("data-callout-position")
16898
+ positionX: "center",
16899
+ positionY: anchorElement.getAttribute("data-callout-position") || "below",
16900
+ positionYFixed: anchorElement.getAttribute("data-callout-position-fixed")
16874
16901
  });
16875
- // data-position-current is written to the clone by pickPositionRelativeTo,
16902
+ // data-position-y-current is written to the clone by pickPositionRelativeTo,
16876
16903
  // copy it back to the real element so stickiness works on next call
16877
- const positionCurrent = calloutElementClone.getAttribute("data-position-current");
16878
- if (positionCurrent) {
16879
- calloutElement.setAttribute("data-position-current", positionCurrent);
16904
+ const positionYCurrent = calloutElementClone.getAttribute("data-position-y-current");
16905
+ if (positionYCurrent) {
16906
+ calloutElement.setAttribute("data-position-y-current", positionYCurrent);
16880
16907
  } else {
16881
- calloutElement.removeAttribute("data-position-current");
16908
+ calloutElement.removeAttribute("data-position-y-current");
16882
16909
  }
16883
16910
  calloutElementClone.remove();
16884
16911
 
@@ -16920,7 +16947,7 @@ const stickCalloutToAnchor = (calloutElement, anchorElement) => {
16920
16947
 
16921
16948
  // Force content overflow when there is not enough space to display
16922
16949
  // the entirety of the callout
16923
- const spaceAvailable = position === "bottom" ? spaceBelow : spaceAbove;
16950
+ const spaceAvailable = positionY === "above" || positionY === "above-overlap" ? spaceAbove : spaceBelow;
16924
16951
  const paddingSizes = getPaddingSizes(calloutBodyElement);
16925
16952
  const paddingY = paddingSizes.top + paddingSizes.bottom;
16926
16953
  const spaceNeededAroundContent = ARROW_HEIGHT + BORDER_WIDTH * 2 + paddingY;
@@ -16939,7 +16966,7 @@ const stickCalloutToAnchor = (calloutElement, anchorElement) => {
16939
16966
  width,
16940
16967
  height
16941
16968
  } = calloutElement.getBoundingClientRect();
16942
- if (position === "top") {
16969
+ if (positionY === "above" || positionY === "above-overlap") {
16943
16970
  // Position above target element
16944
16971
  calloutBoxElement.style.marginTop = "";
16945
16972
  calloutBoxElement.style.marginBottom = `${ARROW_HEIGHT}px`;
@@ -17226,21 +17253,6 @@ const generateSvgWithoutArrow = (width, height) => {
17226
17253
  />
17227
17254
  </svg>`;
17228
17255
  };
17229
- const dispatchCalloutCustomElement = (anchorElement, customEvent) => {
17230
- let targetElement;
17231
- const visualSelector = anchorElement.getAttribute("data-visual-selector");
17232
- if (visualSelector) {
17233
- const visualElement = anchorElement.querySelector(visualSelector);
17234
- if (visualElement) {
17235
- targetElement = visualElement;
17236
- }
17237
- } else {
17238
- targetElement = anchorElement;
17239
- }
17240
-
17241
- // console.log("dispatch on", targetElement, "event", customEvent);
17242
- targetElement.dispatchEvent(customEvent);
17243
- };
17244
17256
 
17245
17257
  /**
17246
17258
  * Creates a live mirror of a source DOM element that automatically stays in sync.
@@ -18697,6 +18709,9 @@ const installCustomConstraintValidation = (
18697
18709
  return element;
18698
18710
  })();
18699
18711
  const onmousedown = (e) => {
18712
+ if (e.button !== 0) {
18713
+ return;
18714
+ }
18700
18715
  if (!validationInterface.validationMessage) {
18701
18716
  return;
18702
18717
  }
@@ -21177,6 +21192,7 @@ const TextUI = props => {
21177
21192
  childrenOutsideFlow,
21178
21193
  ...rest
21179
21194
  } = props;
21195
+ const parentBoxFlow = useContext(BoxFlowContext);
21180
21196
  const defaultSpace = preventSpaceUnderlines ? FAKE_SPACE : REGULAR_SPACE;
21181
21197
  const resolvedSpacing = spacing ?? defaultSpace;
21182
21198
  const boxProps = {
@@ -21186,7 +21202,7 @@ const TextUI = props => {
21186
21202
  ref,
21187
21203
  "baseClassName": withPropsClassName("navi_text", rest.baseClassName)
21188
21204
  };
21189
- const shouldPreserveSpacing = rest.as === "pre" || rest.flex || rest.grid;
21205
+ const shouldPreserveSpacing = rest.as === "pre" || rest.flex || rest.grid || isSpacingHandledByFlow(parentBoxFlow);
21190
21206
  if (shouldPreserveSpacing) {
21191
21207
  boxProps.spacing = resolvedSpacing;
21192
21208
  } else {
@@ -22501,9 +22517,9 @@ const useUIState = (uiStateController) => {
22501
22517
  installImportMetaCssBuild(import.meta);const css$x = /* css */`
22502
22518
  @layer navi {
22503
22519
  .navi_button {
22520
+ --button-border-radius: 2px;
22504
22521
  --button-outline-width: 1px;
22505
22522
  --button-border-width: 1px;
22506
- --button-border-radius: 2px;
22507
22523
  /* Global padding defaults — override these to change all button paddings. */
22508
22524
  /* Use --button-padding, --button-padding-x, --button-padding-y for per-button overrides. */
22509
22525
  --button-padding-x-default: 6px;
@@ -22567,25 +22583,22 @@ installImportMetaCssBuild(import.meta);const css$x = /* css */`
22567
22583
  }
22568
22584
 
22569
22585
  .navi_button {
22570
- /* Internal vars prefixed with --x- to signal they are private, do not use from outside */
22571
- --x-button-outline-width: var(--button-outline-width);
22572
- --x-button-border-radius: var(--button-border-radius);
22573
- --x-button-border-width: var(--button-border-width);
22574
- --x-button-outer-width: calc(
22575
- var(--x-button-border-width) + var(--x-button-outline-width)
22576
- );
22577
- --x-button-outline-color: var(--button-outline-color);
22586
+ /* outline will draw the border when visible */
22587
+ --x-button-outline-width: var(--button-outline-width) +
22588
+ var(--button-border-width);
22589
+ --x-button-outline-offset: calc(-1 * var(--button-border-width));
22578
22590
  --x-button-border-color: var(--button-border-color);
22579
22591
  --x-button-background: var(--button-background);
22580
22592
  --x-button-background-color: var(--button-background-color);
22581
22593
  --x-button-color: var(--button-color);
22582
22594
  --x-button-cursor: var(--button-cursor);
22595
+
22583
22596
  box-sizing: border-box;
22584
22597
  aspect-ratio: inherit;
22585
22598
  padding: 0;
22586
22599
  background: none;
22587
22600
  border: none;
22588
- border-radius: var(--x-button-border-radius);
22601
+ border-radius: var(--button-border-radius);
22589
22602
  outline: none;
22590
22603
  cursor: var(--x-button-cursor);
22591
22604
  -webkit-tap-highlight-color: transparent;
@@ -22645,15 +22658,13 @@ installImportMetaCssBuild(import.meta);const css$x = /* css */`
22645
22658
  --x-button-background-color,
22646
22659
  var(--x-button-background)
22647
22660
  );
22648
-
22649
- border-width: var(--x-button-outer-width);
22661
+ border-width: var(--button-border-width);
22650
22662
  border-style: solid;
22651
- border-color: transparent;
22652
- border-radius: var(--x-button-border-radius);
22653
- outline-width: var(--x-button-border-width);
22654
- outline-style: solid;
22655
- outline-color: var(--x-button-border-color);
22656
- outline-offset: calc(-1 * (var(--x-button-border-width)));
22663
+ border-color: var(--x-button-border-color);
22664
+ border-radius: var(--button-border-radius);
22665
+ outline-width: var(--x-button-outline-width);
22666
+ outline-color: var(--button-outline-color);
22667
+ outline-offset: var(--x-button-outline-offset);
22657
22668
  transition-property: transform;
22658
22669
  transition-duration: 0.15s;
22659
22670
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
@@ -22714,12 +22725,10 @@ installImportMetaCssBuild(import.meta);const css$x = /* css */`
22714
22725
  }
22715
22726
  /* Focus */
22716
22727
  &[data-focus-visible] {
22717
- --x-button-border-color: var(--x-button-outline-color);
22718
- }
22719
- &[data-focus-visible] {
22728
+ --x-button-border-color: transparent;
22729
+
22720
22730
  .navi_button_content {
22721
- outline-width: var(--x-button-outer-width);
22722
- outline-offset: calc(-1 * var(--x-button-outer-width));
22731
+ outline-style: solid;
22723
22732
  }
22724
22733
  }
22725
22734
  /* Disabled */
@@ -22842,6 +22851,7 @@ const ButtonUI = props => {
22842
22851
  const renderButtonContent = buttonProps => {
22843
22852
  return jsxs(Text, {
22844
22853
  ...buttonProps,
22854
+ display: "inherit",
22845
22855
  spacing: spacing,
22846
22856
  className: "navi_button_content",
22847
22857
  children: [children, jsx(ButtonShadow, {})]
@@ -28138,7 +28148,6 @@ const ListWithPopover = props => {
28138
28148
  left,
28139
28149
  top
28140
28150
  } = pickPositionRelativeTo(listContainerEl, anchor, {
28141
- positionTry: "bottom",
28142
28151
  minLeft
28143
28152
  });
28144
28153
  listContainerEl.style.top = `${top}px`;
@@ -28928,7 +28937,6 @@ const css$k = /* css */`
28928
28937
  --border-radius: 2px;
28929
28938
  --border-width: 1px;
28930
28939
  --outline-width: 1px;
28931
- --outer-width: calc(var(--border-width) + var(--outline-width));
28932
28940
  --font-size: 14px;
28933
28941
 
28934
28942
  /* Default */
@@ -28972,6 +28980,16 @@ const css$k = /* css */`
28972
28980
  }
28973
28981
 
28974
28982
  .navi_input {
28983
+ /* outline will draw the border when visible */
28984
+ --x-outline-width: var(--outline-width) + var(--border-width);
28985
+ --x-outline-offset: calc(-1 * var(--border-width));
28986
+ --left-slot-size: 0px;
28987
+ --right-slot-size: 0px;
28988
+ --x-border-color: var(--border-color);
28989
+ --x-background-color: var(--background-color);
28990
+ --x-color: var(--color);
28991
+ --x-placeholder-color: var(--placeholder-color);
28992
+
28975
28993
  position: relative;
28976
28994
  box-sizing: border-box;
28977
28995
  width: fit-content;
@@ -28980,18 +28998,6 @@ const css$k = /* css */`
28980
28998
  border-radius: inherit;
28981
28999
  cursor: inherit;
28982
29000
 
28983
- --left-slot-size: 0px;
28984
- --right-slot-size: 0px;
28985
- --x-outline-width: var(--outline-width);
28986
- --x-border-radius: var(--border-radius);
28987
- --x-border-width: var(--border-width);
28988
- --x-outer-width: calc(var(--x-border-width) + var(--x-outline-width));
28989
- --x-outline-color: var(--outline-color);
28990
- --x-border-color: var(--border-color);
28991
- --x-background-color: var(--background-color);
28992
- --x-color: var(--color);
28993
- --x-placeholder-color: var(--placeholder-color);
28994
-
28995
29001
  --x-padding-top-base: var(
28996
29002
  --padding-top,
28997
29003
  var(--padding-y, var(--padding, 1px))
@@ -29019,15 +29025,13 @@ const css$k = /* css */`
29019
29025
  color: var(--x-color);
29020
29026
  font-size: var(--font-size);
29021
29027
  background-color: var(--x-background-color);
29022
- border-width: var(--x-outer-width);
29023
- border-width: var(--x-outer-width);
29028
+ border-width: var(--border-width);
29024
29029
  border-style: solid;
29025
- border-color: transparent;
29026
- border-radius: var(--x-border-radius);
29027
- outline-width: var(--x-border-width);
29028
- outline-style: solid;
29029
- outline-color: var(--x-border-color);
29030
- outline-offset: calc(-1 * (var(--x-border-width)));
29030
+ border-color: var(--x-border-color);
29031
+ border-radius: var(--border-radius);
29032
+ outline-width: var(--x-outline-width);
29033
+ outline-color: var(--outline-color);
29034
+ outline-offset: var(--x-outline-offset);
29031
29035
 
29032
29036
  &[type="search"] {
29033
29037
  -webkit-appearance: textfield;
@@ -29107,12 +29111,10 @@ const css$k = /* css */`
29107
29111
  &[data-focus],
29108
29112
  &[data-focus-visible] {
29109
29113
  --x-background-color: var(--background-color-focus);
29110
- --x-border-color: var(--border-color-focus);
29114
+ --x-border-color: transparent;
29111
29115
 
29112
29116
  .navi_native_input {
29113
- outline-width: var(--x-outer-width);
29114
- outline-offset: calc(-1 * var(--x-outer-width));
29115
- --x-border-color: var(--x-outline-color);
29117
+ outline-style: solid;
29116
29118
  }
29117
29119
  }
29118
29120
  /* Disabled */
@@ -29407,7 +29409,13 @@ const InputSlot = ({
29407
29409
  flex: true,
29408
29410
  alignY: "center",
29409
29411
  onMouseDown: e => {
29410
- e.preventDefault(); // keep focus in the input
29412
+ // Only prevent focus from leaving when the input already has focus.
29413
+ // If the input is not focused, let the mousedown proceed normally so
29414
+ // the slot element (e.g. a clear button) can receive focus itself.
29415
+ const inputEl = document.getElementById(id);
29416
+ if (inputEl && inputEl === document.activeElement) {
29417
+ e.preventDefault();
29418
+ }
29411
29419
  },
29412
29420
  onClick: e => {
29413
29421
  if (readOnly || disabled) {
@@ -30595,12 +30603,12 @@ const Dialog = props => {
30595
30603
  } = props;
30596
30604
  const defaultRef = useRef();
30597
30605
  const ref = rest.ref || defaultRef;
30598
- const debugPopover = useDebugPopover();
30606
+ const debugPopup = useDebugPopup();
30599
30607
  const debugFocus = useDebugFocus();
30600
30608
  const openedRef = useRef(false);
30601
30609
  const [addCleanup, cleanup] = useCleanup();
30602
30610
  const open = e => {
30603
- debugPopover(`openDialog("${e.type}")`);
30611
+ debugPopup(`"${e.type}" on ${getElementSignature(e.target)} -> openDialog`);
30604
30612
  const dialogEl = ref.current;
30605
30613
  dialogEl.showModal();
30606
30614
  const firstFocusable = findFocusable(dialogEl);
@@ -30619,7 +30627,7 @@ const Dialog = props => {
30619
30627
  });
30620
30628
  };
30621
30629
  const close = e => {
30622
- debugPopover(`closeDialog("${e.type}")`);
30630
+ debugPopup(`"${e.type}" on ${getElementSignature(e.target)} -> closeDialog`);
30623
30631
  const dialogEl = ref.current;
30624
30632
  dialogEl.close();
30625
30633
  cleanup();
@@ -30719,14 +30727,17 @@ const Popover = props => {
30719
30727
  pointerTrap,
30720
30728
  focusTrap,
30721
30729
  children,
30722
- positionTry = "bottom",
30730
+ positionX,
30731
+ positionY,
30732
+ positionXFixed,
30733
+ positionYFixed,
30723
30734
  ...rest
30724
30735
  } = props;
30725
30736
  const defaultRef = useRef();
30726
30737
  const ref = rest.ref || defaultRef;
30727
30738
  const defaultId = useId();
30728
30739
  const id = rest.id || defaultId;
30729
- const debugPopover = useDebugPopover();
30740
+ const debugPopup = useDebugPopup();
30730
30741
  const debugFocus = useDebugFocus();
30731
30742
  const [opened, setOpened] = useState(false);
30732
30743
  const openedRef = useRef(opened);
@@ -30735,7 +30746,7 @@ const Popover = props => {
30735
30746
  const open = (e, {
30736
30747
  anchor
30737
30748
  }) => {
30738
- debugPopover(`openPopover("${e.type}")`);
30749
+ debugPopup(`openPopover("${e.type}")`);
30739
30750
  const popoverEl = ref.current;
30740
30751
  popoverEl.showPopover();
30741
30752
  const firstFocusable = findFocusable(popoverEl);
@@ -30747,27 +30758,27 @@ const Popover = props => {
30747
30758
  }
30748
30759
  const effectiveAnchor = anchor || document.documentElement;
30749
30760
  const positionPopover = positionEvent => {
30750
- debugPopover(`positionPopover("${positionEvent.type}")`);
30751
- popoverEl.style.setProperty("--anchor-width", `${effectiveAnchor.getBoundingClientRect().width}px`);
30761
+ const {
30762
+ width,
30763
+ height
30764
+ } = effectiveAnchor.getBoundingClientRect();
30765
+ popoverEl.style.setProperty("--anchor-width", `${width}px`);
30766
+ popoverEl.style.setProperty("--anchor-height", `${height}px`);
30752
30767
  const minLeft = 1;
30753
- const effectivePositionTry = anchor ? positionTry : "center";
30768
+ const effectivePositionX = anchor ? positionX : "center";
30754
30769
  const {
30755
30770
  left,
30756
30771
  top
30757
30772
  } = pickPositionRelativeTo(popoverEl, effectiveAnchor, {
30758
- positionTry: effectivePositionTry,
30773
+ positionX: effectivePositionX,
30774
+ positionY,
30775
+ positionXFixed,
30776
+ positionYFixed,
30759
30777
  minLeft
30760
30778
  });
30779
+ debugPopup(`positionPopover("${positionEvent.type}") -> left: ${left}, top: ${top}`);
30761
30780
  popoverEl.style.top = `${top}px`;
30762
- const popoverRect = popoverEl.getBoundingClientRect();
30763
- const maxWidth = parseFloat(getComputedStyle(popoverEl).maxWidth);
30764
- if (!isNaN(maxWidth) && popoverRect.width >= maxWidth - 1) {
30765
- const viewportWidth = document.documentElement.clientWidth;
30766
- const centeredLeft = (viewportWidth - popoverRect.width) / 2;
30767
- popoverEl.style.left = `${Math.max(centeredLeft, minLeft)}px`;
30768
- } else {
30769
- popoverEl.style.left = `${Math.max(left, minLeft)}px`;
30770
- }
30781
+ popoverEl.style.left = `${Math.max(left, minLeft)}px`;
30771
30782
  };
30772
30783
  if (scrollTrap) {
30773
30784
  addCleanup(trapScrollInside(popoverEl));
@@ -30799,7 +30810,7 @@ const Popover = props => {
30799
30810
  });
30800
30811
  };
30801
30812
  const close = e => {
30802
- debugPopover(`closePopover("${e.type}")`);
30813
+ debugPopup(`closePopover("${e.type}")`);
30803
30814
  const popoverEl = ref.current;
30804
30815
  popoverEl.hidePopover();
30805
30816
  cleanup();
@@ -30853,6 +30864,7 @@ const Popover = props => {
30853
30864
  ...rest,
30854
30865
  ref: ref,
30855
30866
  baseClassName: "navi_popover",
30867
+ pseudoClasses: PopoverPseudoClasses,
30856
30868
  onnavi_popover_request_open: e => {
30857
30869
  const {
30858
30870
  event = e,
@@ -30872,6 +30884,7 @@ const Popover = props => {
30872
30884
  })]
30873
30885
  });
30874
30886
  };
30887
+ const PopoverPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":focus-within", ":read-only", ":disabled"];
30875
30888
  const requestPopoverOpen = (popoverElement, {
30876
30889
  event,
30877
30890
  anchor
@@ -30893,11 +30906,12 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
30893
30906
  @layer navi {
30894
30907
  .navi_select {
30895
30908
  --select-border-radius: 2px;
30896
- --select-border-width: 1px;
30897
30909
  --select-outline-width: 1px;
30910
+ --select-border-width: 1px;
30898
30911
  --select-font-size: 14px;
30899
30912
  --select-padding-x-default: 8px;
30900
30913
  --select-padding-y-default: 5px;
30914
+ --select-outline-color: var(--navi-focus-outline-color);
30901
30915
  --select-border-color: light-dark(#767676, #8e8e93);
30902
30916
  --select-background-color: white;
30903
30917
  --select-color: currentColor;
@@ -30920,60 +30934,66 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
30920
30934
  }
30921
30935
 
30922
30936
  .navi_select {
30923
- position: relative;
30924
- box-sizing: border-box;
30925
- padding-top: var(
30937
+ --x-select-background-color: var(--select-background-color);
30938
+ --x-select-border-color: var(--select-border-color);
30939
+ /* outline will draw the border when visible */
30940
+ --x-select-outline-width: calc(
30941
+ var(--select-outline-width) + var(--select-border-width)
30942
+ );
30943
+ --x-select-outline-offset: calc(-1 * var(--select-border-width));
30944
+ --x-select-padding-top: var(
30926
30945
  --select-padding-top,
30927
30946
  var(--select-padding-y, var(--select-padding-y-default))
30928
30947
  );
30929
- padding-right: var(
30948
+ --x-select-padding-right: var(
30930
30949
  --select-padding-right,
30931
30950
  var(--select-padding-x, var(--select-padding-x-default))
30932
30951
  );
30933
- padding-bottom: var(
30934
- --select-padding-bottom,
30935
- var(--select-padding-y, var(--select-padding-y-default))
30936
- );
30937
- padding-left: var(
30952
+ --x-select-padding-left: var(
30938
30953
  --select-padding-left,
30939
30954
  var(--select-padding-x, var(--select-padding-x-default))
30940
30955
  );
30956
+ --x-select-padding-bottom: var(
30957
+ --select-padding-bottom,
30958
+ var(--select-padding-y, var(--select-padding-y-default))
30959
+ );
30960
+
30961
+ position: relative;
30962
+ box-sizing: border-box;
30963
+ padding-top: var(--x-select-padding-top);
30964
+ padding-right: var(--x-select-padding-right);
30965
+ padding-bottom: var(--x-select-padding-bottom);
30966
+ padding-left: var(--x-select-padding-left);
30941
30967
  color: var(--select-color);
30942
30968
  font-size: var(--select-font-size);
30943
30969
  text-align: inherit; /* override browser defaults on button which is center */
30944
30970
  white-space: nowrap; /* Prevent icon from going next line */
30945
- background-color: var(--select-background-color);
30946
- border: var(--select-border-width) solid transparent;
30971
+ background-color: var(--x-select-background-color);
30972
+ border-width: var(--select-border-width);
30973
+ border-style: solid;
30974
+ border-color: var(--x-select-border-color);
30947
30975
  border-radius: var(--select-border-radius);
30948
- outline: var(--select-outline-width) solid var(--select-border-color);
30949
- outline-offset: calc(-1 * var(--select-outline-width));
30976
+ outline-width: var(--x-select-outline-width);
30977
+ outline-color: var(--select-outline-color);
30978
+ outline-offset: var(--x-select-outline-offset);
30950
30979
  user-select: none;
30951
30980
 
30952
- --x-select-outline-width-focus-visible: calc(
30953
- var(--select-border-width) + var(--select-outline-width)
30954
- );
30955
- --x-select-outline-offset-focus-visible: calc(
30956
- -1 * (var(--select-border-width) + var(--select-outline-width))
30957
- );
30958
-
30959
30981
  &[data-hover] {
30960
- background-color: var(--select-background-color-hover);
30961
- outline-color: var(--select-border-color-hover);
30982
+ --x-select-background-color: var(--select-background-color-hover);
30983
+ --x-select-border-color: var(--select-border-color-hover);
30962
30984
  }
30963
30985
 
30964
30986
  &[data-focus-visible] {
30965
- outline-width: var(--x-select-outline-width-focus-visible);
30966
- outline-color: var(--navi-focus-outline-color);
30967
- outline-offset: var(--x-select-outline-offset-focus-visible);
30987
+ --x-select-border-color: transparent;
30988
+ outline-style: solid;
30968
30989
  }
30969
30990
 
30970
30991
  &[data-disabled] {
30971
30992
  opacity: 0.5;
30972
30993
  cursor: default;
30973
30994
  }
30974
-
30975
- .navi_list_container {
30976
- --list-border-radius: 0;
30995
+ &[data-callout] {
30996
+ --x-select-border-color: var(--callout-color);
30977
30997
  }
30978
30998
 
30979
30999
  .navi_select_trigger_text {
@@ -31001,19 +31021,21 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
31001
31021
  }
31002
31022
  }
31003
31023
  .navi_select_trigger_icon {
31004
- margin-left: 6px;
31005
31024
  flex-shrink: 0;
31006
31025
  opacity: 0.6;
31007
31026
  }
31008
31027
 
31009
31028
  /* popover */
31010
31029
  &[aria-haspopup="listbox"] {
31011
- &:has(.navi_list_container[data-focus-visible]) {
31012
- outline-width: var(--x-select-outline-width-focus-visible);
31013
- outline-color: var(--navi-focus-outline-color);
31014
- outline-offset: var(--x-select-outline-offset-focus-visible);
31015
- .navi_list_container {
31016
- outline: none;
31030
+ .navi_list_container {
31031
+ width: 100%;
31032
+ /* Handled by the popover */
31033
+ border: none;
31034
+ border-radius: 0;
31035
+ outline: none;
31036
+
31037
+ .navi_list {
31038
+ width: 100%;
31017
31039
  }
31018
31040
  }
31019
31041
 
@@ -31022,18 +31044,79 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
31022
31044
  inset: unset;
31023
31045
  min-width: var(--anchor-width, 0px);
31024
31046
  max-width: 95vw;
31047
+ /* max-height covers the placeholder + list; the list scrolls internally */
31025
31048
  max-height: 95dvh;
31026
31049
  margin: 0;
31027
31050
  padding: 0;
31028
- background: white;
31029
- border: none;
31030
- border-radius: 0;
31051
+ background: var(--select-background-color);
31052
+ border-width: var(--select-border-width);
31053
+ border-style: solid;
31054
+ border-color: var(--x-select-border-color);
31055
+ border-radius: var(--select-border-radius);
31056
+ outline-width: var(--x-select-outline-width);
31057
+ outline-color: var(--select-outline-color);
31058
+ outline-offset: var(--x-select-outline-offset);
31031
31059
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
31032
31060
  cursor: default; /* Reset pointer cursor within the select */
31033
- overflow: auto;
31061
+ overflow: hidden;
31034
31062
  overscroll-behavior: none;
31035
31063
 
31036
- &:popover-open {
31064
+ /* The anchor placeholder is a non-interactive visual clone of the
31065
+ trigger. It makes the popover wrap both the trigger area and the list
31066
+ under a single border/shadow. CSS order places it before the list
31067
+ when the popover is below the trigger, and after when above. */
31068
+ .navi_select_anchor_clone {
31069
+ /* Mirror the trigger's padding so the clone looks identical */
31070
+ padding-top: var(--x-select-padding-top);
31071
+ padding-right: var(--x-select-padding-right);
31072
+ padding-bottom: var(--x-select-padding-bottom);
31073
+ padding-left: var(--x-select-padding-left);
31074
+ flex-shrink: 0;
31075
+ order: -1; /* before the list — popover is below the trigger */
31076
+ background: var(--x-select-background-color);
31077
+ border-bottom: var(--select-border-width) solid
31078
+ var(--x-select-border-color);
31079
+
31080
+ &:hover {
31081
+ --x-select-background-color: var(--select-background-color-hover);
31082
+ --x-select-border-color: var(--select-border-color-hover);
31083
+ }
31084
+ }
31085
+
31086
+ &[data-position-y-current="above"],
31087
+ &[data-position-y-current="above-overlap"] {
31088
+ .navi_select_anchor_clone {
31089
+ order: 1; /* after the list — popover is above the trigger */
31090
+ border-top: var(--select-border-width) solid
31091
+ var(--x-select-border-color);
31092
+ border-bottom: none;
31093
+ }
31094
+ }
31095
+
31096
+ /* The list scrolls inside the popover */
31097
+ .navi_list_container {
31098
+ overflow: auto;
31099
+ overscroll-behavior: none;
31100
+ }
31101
+ }
31102
+
31103
+ &:has([data-hover]) {
31104
+ .navi_select_popover {
31105
+ --x-select-border-color: var(--select-border-color-hover);
31106
+ }
31107
+ }
31108
+ &:has([data-focus-visible]) {
31109
+ .navi_select_popover {
31110
+ outline-style: solid;
31111
+ }
31112
+ }
31113
+
31114
+ &[aria-expanded="true"] {
31115
+ border-top-color: var(--select-border-color);
31116
+ border-top-left-radius: 0;
31117
+ border-top-right-radius: 0;
31118
+
31119
+ .navi_select_popover {
31037
31120
  display: flex;
31038
31121
  flex-direction: column;
31039
31122
  }
@@ -31043,17 +31126,15 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
31043
31126
  /* dialog */
31044
31127
  &[aria-haspopup="dialog"] {
31045
31128
  .navi_list_container {
31129
+ width: 100%;
31046
31130
  --list-max-height: none;
31047
- }
31131
+ /* Handled by the dialog */
31132
+ border: none;
31133
+ border-radius: 0;
31134
+ outline: none;
31048
31135
 
31049
- /* When the list inside the dialog has keyboard focus, show the focus ring
31050
- on the dialog instead */
31051
- &:has(.navi_list_container[data-focus-visible]) {
31052
- outline-width: var(--x-select-outline-width-focus-visible);
31053
- outline-color: var(--navi-focus-outline-color);
31054
- outline-offset: var(--x-select-outline-offset-focus-visible);
31055
- .navi_list_container {
31056
- outline: none;
31136
+ .navi_list {
31137
+ width: 100%;
31057
31138
  }
31058
31139
  }
31059
31140
 
@@ -31061,9 +31142,12 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
31061
31142
  max-height: 95dvh;
31062
31143
  margin: auto;
31063
31144
  padding: 0;
31064
- background: white;
31065
- border: none;
31066
- border-radius: 8px;
31145
+ background: var(--select-background-color);
31146
+ border: var(--select-border-width) solid var(--x-select-border-color);
31147
+ border-radius: var(--select-border-radius);
31148
+ outline-width: var(--x-select-outline-width);
31149
+ outline-color: var(--select-outline-color);
31150
+ outline-offset: var(--x-select-outline-offset);
31067
31151
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
31068
31152
  cursor: default; /* Reset pointer cursor within the select */
31069
31153
 
@@ -31076,6 +31160,14 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
31076
31160
  background: rgba(0, 0, 0, 0.4);
31077
31161
  }
31078
31162
  }
31163
+
31164
+ /* When the list inside the dialog has keyboard focus, show the focus ring
31165
+ on the dialog instead */
31166
+ &:has([data-focus-visible]) {
31167
+ .navi_select_dialog {
31168
+ outline-style: solid;
31169
+ }
31170
+ }
31079
31171
  }
31080
31172
  }
31081
31173
  `;
@@ -31119,6 +31211,7 @@ const Select = props => {
31119
31211
  return jsx(ParentUIStateControllerContext.Provider, {
31120
31212
  value: uiStateController,
31121
31213
  children: jsx(SelectDispatcher, {
31214
+ trigger: jsx(SelectTrigger, {}),
31122
31215
  ...props,
31123
31216
  ref: ref,
31124
31217
  value: value
@@ -31147,7 +31240,7 @@ const SelectDispatcher = props => {
31147
31240
  };
31148
31241
  const SelectUI = props => {
31149
31242
  import.meta.css = [css$f, "@jsenv/navi/src/field/select.jsx"];
31150
- let {
31243
+ const {
31151
31244
  placeholder = "Select…",
31152
31245
  trigger,
31153
31246
  name,
@@ -31178,9 +31271,6 @@ const SelectUI = props => {
31178
31271
  useAutoFocus(ref, autoFocus, {
31179
31272
  preventScroll: autoFocusPreventScroll
31180
31273
  });
31181
- if (trigger === undefined) {
31182
- trigger = jsx(SelectTrigger, {});
31183
- }
31184
31274
  return jsxs(Box, {
31185
31275
  as: "button",
31186
31276
  type: "button",
@@ -31223,6 +31313,7 @@ const SelectUI = props => {
31223
31313
  const SelectPlaceholderContext = createContext();
31224
31314
  const SelectValueContext = createContext(null);
31225
31315
  const SelectStyleCSSVars = {
31316
+ "outlineWidth": "--select-outline-width",
31226
31317
  "borderWidth": "--select-border-width",
31227
31318
  "borderRadius": "--select-border-radius",
31228
31319
  "paddingX": "--select-padding-x",
@@ -31260,14 +31351,16 @@ const SelectStyleCSSVars = {
31260
31351
  color: "--select-color-disabled"
31261
31352
  }
31262
31353
  };
31263
- const SelectPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading", ":-navi-expanded"];
31354
+ const SelectPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":focus-within", ":read-only", ":disabled", ":-navi-loading", ":-navi-expanded"];
31264
31355
  const SelectPseudoElements = ["::-navi-loader"];
31265
31356
  const SelectTrigger = () => {
31266
31357
  const placeholder = useContext(SelectPlaceholderContext);
31267
31358
  const value = useContext(SelectValueContext);
31268
31359
  const hasValue = value !== null && value !== undefined && value !== "";
31269
31360
  const isPlaceholder = !hasValue;
31270
- return jsxs(Fragment, {
31361
+ return jsxs(Box, {
31362
+ flex: true,
31363
+ spacing: "s",
31271
31364
  children: [jsxs("span", {
31272
31365
  className: "navi_select_trigger_text",
31273
31366
  children: [jsx("span", {
@@ -31293,13 +31386,13 @@ const SelectWithPopover = props => {
31293
31386
  disabled,
31294
31387
  onKeyDown,
31295
31388
  children,
31296
- positionTry,
31297
31389
  pointerTrap,
31298
31390
  scrollTrap = true,
31299
31391
  focusTrap = true,
31300
31392
  ...rest
31301
31393
  } = props;
31302
31394
  const debugFocus = useDebugFocus();
31395
+ const debugPopup = useDebugPopup();
31303
31396
  const popoverRef = useRef(null);
31304
31397
  const popoverId = useId();
31305
31398
  const [expanded, setExpanded] = useState(false);
@@ -31314,12 +31407,21 @@ const SelectWithPopover = props => {
31314
31407
  setExpanded(false);
31315
31408
  };
31316
31409
  const requestOpen = e => {
31410
+ // scroll select into view when opening it
31411
+ ref.current.scrollIntoView({
31412
+ block: "nearest"
31413
+ });
31317
31414
  return requestPopoverOpen(popoverRef.current, {
31318
31415
  event: e,
31319
31416
  anchor: ref.current
31320
31417
  });
31321
31418
  };
31419
+ const [shouldIgnoreThatClick, disableClickFor] = useIgnoreClickForMousedown();
31322
31420
  const requestClose = (e = new CustomEvent("programmatic")) => {
31421
+ if (e.type === "mousedown") {
31422
+ debugPopup(formatEventSideEffect(e, `disable click`));
31423
+ disableClickFor(e);
31424
+ }
31323
31425
  return requestPopoverClose(popoverRef.current, {
31324
31426
  event: e
31325
31427
  });
@@ -31331,7 +31433,6 @@ const SelectWithPopover = props => {
31331
31433
  preventScroll: true
31332
31434
  });
31333
31435
  };
31334
- const [shouldIgnoreThatClick, disableClickFor] = useIgnoreClickForMousedown();
31335
31436
  return jsx(SelectDispatcher, {
31336
31437
  disabled: disabled,
31337
31438
  "aria-haspopup": "listbox",
@@ -31358,6 +31459,7 @@ const SelectWithPopover = props => {
31358
31459
  return;
31359
31460
  }
31360
31461
  if (shouldIgnoreThatClick) {
31462
+ debugPopup(formatEventSideEffect(e, `ignore click`));
31361
31463
  return;
31362
31464
  }
31363
31465
  // When a label is clicked it transfers focus to the select
@@ -31379,8 +31481,8 @@ const SelectWithPopover = props => {
31379
31481
  // space can open the popover we don't want space to propagate to the select otherwise it would open it back immediatly
31380
31482
  event.stopPropagation();
31381
31483
  }
31382
- requestClose(e);
31383
- moveFocusToSelect(e);
31484
+ requestClose(event);
31485
+ moveFocusToSelect(event);
31384
31486
  },
31385
31487
  onFocusOut: e => {
31386
31488
  // Close when focus leaves the select entirely (not just moving between internal elements).
@@ -31418,7 +31520,7 @@ const SelectWithPopover = props => {
31418
31520
  }, onKeyDown),
31419
31521
  ref: ref,
31420
31522
  mode: "ui",
31421
- children: jsx(Popover, {
31523
+ children: jsxs(Popover, {
31422
31524
  ref: popoverRef,
31423
31525
  className: "navi_select_popover",
31424
31526
  onMouseDown: e => {
@@ -31427,7 +31529,6 @@ const SelectWithPopover = props => {
31427
31529
  }
31428
31530
  // mousedown inside popover should not bubble to the select (would re-open it if that mousedown closes it)
31429
31531
  e.stopPropagation();
31430
- disableClickFor(e);
31431
31532
  },
31432
31533
  onnavi_popover_open: e => {
31433
31534
  onOpen();
@@ -31438,17 +31539,27 @@ const SelectWithPopover = props => {
31438
31539
  event = e
31439
31540
  } = e.detail;
31440
31541
  if (event.type === "focusout") ; else {
31441
- moveFocusToSelect(e);
31542
+ moveFocusToSelect(event);
31442
31543
  }
31443
31544
  },
31444
- positionTry: positionTry,
31545
+ positionX: "left-aligned",
31546
+ positionY: "below-overlap",
31445
31547
  scrollTrap: scrollTrap,
31446
31548
  pointerTrap: pointerTrap,
31447
31549
  focusTrap: focusTrap,
31448
- children: jsx(SelectRequestCloseContext.Provider, {
31550
+ children: [jsx("div", {
31551
+ className: "navi_select_anchor_clone",
31552
+ onMouseDown: e => {
31553
+ if (e.button !== 0) {
31554
+ return;
31555
+ }
31556
+ requestClose(e);
31557
+ },
31558
+ children: props.trigger
31559
+ }), jsx(SelectRequestCloseContext.Provider, {
31449
31560
  value: requestClose,
31450
31561
  children: children
31451
- })
31562
+ })]
31452
31563
  })
31453
31564
  });
31454
31565
  };
@@ -31464,6 +31575,7 @@ const SelectWithDialog = props => {
31464
31575
  ...rest
31465
31576
  } = props;
31466
31577
  const debugFocus = useDebugFocus();
31578
+ const debugPopup = useDebugPopup();
31467
31579
  const dialogRef = useRef(null);
31468
31580
  const dialogId = useId();
31469
31581
  const [expanded, setExpanded] = useState(false);
@@ -31482,7 +31594,12 @@ const SelectWithDialog = props => {
31482
31594
  event: e
31483
31595
  });
31484
31596
  };
31597
+ const [shouldIgnore, disableClickFor] = useIgnoreClickForMousedown();
31485
31598
  const requestClose = (e = new CustomEvent("programmatic")) => {
31599
+ if (e.type === "mousedown") {
31600
+ debugPopup(formatEventSideEffect(e, `disable click`));
31601
+ disableClickFor(e);
31602
+ }
31486
31603
  return requestDialogClose(dialogRef.current, {
31487
31604
  event: e
31488
31605
  });
@@ -31493,7 +31610,6 @@ const SelectWithDialog = props => {
31493
31610
  preventScroll: true
31494
31611
  });
31495
31612
  };
31496
- const [shouldIgnoreThatClick, disableClickFor] = useIgnoreClickForMousedown();
31497
31613
  return jsx(SelectDispatcher, {
31498
31614
  disabled: disabled,
31499
31615
  "aria-haspopup": "dialog",
@@ -31519,7 +31635,8 @@ const SelectWithDialog = props => {
31519
31635
  // click triggered by enter won't open the dialog
31520
31636
  return;
31521
31637
  }
31522
- if (shouldIgnoreThatClick) {
31638
+ if (shouldIgnore) {
31639
+ debugPopup(formatEventSideEffect(e, `ignore click`));
31523
31640
  // mousedown on the select already handled open/close; ignore this click
31524
31641
  // to avoid toggling the dialog again on mouseup
31525
31642
  return;
@@ -31535,7 +31652,7 @@ const SelectWithDialog = props => {
31535
31652
  // space can open the dialog, we don't want space to propagate to the select otherwise it would open it back immediately
31536
31653
  event.stopPropagation();
31537
31654
  }
31538
- requestClose(e);
31655
+ requestClose(event);
31539
31656
  },
31540
31657
  ...rest,
31541
31658
  onKeyDown: shortcutsViaOnKeyDown({
@@ -31579,7 +31696,6 @@ const SelectWithDialog = props => {
31579
31696
  }
31580
31697
  // mousedown inside dialog should not bubble to the select (would re-open it if that mousedown closes it)
31581
31698
  e.stopPropagation();
31582
- disableClickFor(e);
31583
31699
  },
31584
31700
  scrollTrap: scrollTrap,
31585
31701
  pointerTrap: pointerTrap,