@jsenv/navi 0.26.3 → 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.
- package/dist/jsenv_navi.js +289 -187
- package/dist/jsenv_navi.js.map +27 -22
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -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,
|
|
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
|
|
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
|
|
2464
|
-
const debug = useContext(
|
|
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
|
-
*
|
|
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
|
-
|
|
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 (
|
|
2491
|
-
|
|
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(
|
|
2498
|
-
value:
|
|
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) {
|
|
@@ -7647,6 +7650,11 @@ definePseudoClass(":active", {
|
|
|
7647
7650
|
if (isControlledByFocusedElement(el)) {
|
|
7648
7651
|
return true;
|
|
7649
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
|
+
}
|
|
7650
7658
|
return false;
|
|
7651
7659
|
},
|
|
7652
7660
|
});
|
|
@@ -16599,14 +16607,22 @@ const openCallout = (message, {
|
|
|
16599
16607
|
}
|
|
16600
16608
|
allowWheelThrough(calloutElement, anchorElement);
|
|
16601
16609
|
anchorElement.setAttribute("data-callout", calloutId);
|
|
16602
|
-
dispatchCalloutCustomElement(anchorElement, new CustomEvent("navi_callout_open", {
|
|
16603
|
-
bubbles: true
|
|
16604
|
-
}));
|
|
16605
16610
|
addTeardown(() => {
|
|
16606
16611
|
anchorElement.removeAttribute("data-callout");
|
|
16607
|
-
|
|
16608
|
-
|
|
16609
|
-
|
|
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");
|
|
16610
16626
|
});
|
|
16611
16627
|
addStatusEffect(status => {
|
|
16612
16628
|
if (!status) {
|
|
@@ -16869,7 +16885,7 @@ const stickCalloutToAnchor = (calloutElement, anchorElement) => {
|
|
|
16869
16885
|
}) => {
|
|
16870
16886
|
const calloutElementClone = cloneCalloutToMeasureNaturalSize(calloutElement);
|
|
16871
16887
|
const {
|
|
16872
|
-
|
|
16888
|
+
positionY,
|
|
16873
16889
|
left: calloutLeft,
|
|
16874
16890
|
top: calloutTop,
|
|
16875
16891
|
width: calloutWidth,
|
|
@@ -16877,20 +16893,19 @@ const stickCalloutToAnchor = (calloutElement, anchorElement) => {
|
|
|
16877
16893
|
spaceAbove,
|
|
16878
16894
|
spaceBelow
|
|
16879
16895
|
} = pickPositionRelativeTo(calloutElementClone, anchorElement, {
|
|
16880
|
-
|
|
16881
|
-
// when fully to the left, the border color is collé to the browser window making it hard to see
|
|
16896
|
+
alignToViewportEdgeWhenAnchorNearEdge: 20,
|
|
16882
16897
|
minLeft: 1,
|
|
16883
|
-
|
|
16884
|
-
|
|
16885
|
-
|
|
16898
|
+
positionX: "center",
|
|
16899
|
+
positionY: anchorElement.getAttribute("data-callout-position") || "below",
|
|
16900
|
+
positionYFixed: anchorElement.getAttribute("data-callout-position-fixed")
|
|
16886
16901
|
});
|
|
16887
|
-
// data-position-current is written to the clone by pickPositionRelativeTo,
|
|
16902
|
+
// data-position-y-current is written to the clone by pickPositionRelativeTo,
|
|
16888
16903
|
// copy it back to the real element so stickiness works on next call
|
|
16889
|
-
const
|
|
16890
|
-
if (
|
|
16891
|
-
calloutElement.setAttribute("data-position-current",
|
|
16904
|
+
const positionYCurrent = calloutElementClone.getAttribute("data-position-y-current");
|
|
16905
|
+
if (positionYCurrent) {
|
|
16906
|
+
calloutElement.setAttribute("data-position-y-current", positionYCurrent);
|
|
16892
16907
|
} else {
|
|
16893
|
-
calloutElement.removeAttribute("data-position-current");
|
|
16908
|
+
calloutElement.removeAttribute("data-position-y-current");
|
|
16894
16909
|
}
|
|
16895
16910
|
calloutElementClone.remove();
|
|
16896
16911
|
|
|
@@ -16932,7 +16947,7 @@ const stickCalloutToAnchor = (calloutElement, anchorElement) => {
|
|
|
16932
16947
|
|
|
16933
16948
|
// Force content overflow when there is not enough space to display
|
|
16934
16949
|
// the entirety of the callout
|
|
16935
|
-
const spaceAvailable =
|
|
16950
|
+
const spaceAvailable = positionY === "above" || positionY === "above-overlap" ? spaceAbove : spaceBelow;
|
|
16936
16951
|
const paddingSizes = getPaddingSizes(calloutBodyElement);
|
|
16937
16952
|
const paddingY = paddingSizes.top + paddingSizes.bottom;
|
|
16938
16953
|
const spaceNeededAroundContent = ARROW_HEIGHT + BORDER_WIDTH * 2 + paddingY;
|
|
@@ -16951,7 +16966,7 @@ const stickCalloutToAnchor = (calloutElement, anchorElement) => {
|
|
|
16951
16966
|
width,
|
|
16952
16967
|
height
|
|
16953
16968
|
} = calloutElement.getBoundingClientRect();
|
|
16954
|
-
if (
|
|
16969
|
+
if (positionY === "above" || positionY === "above-overlap") {
|
|
16955
16970
|
// Position above target element
|
|
16956
16971
|
calloutBoxElement.style.marginTop = "";
|
|
16957
16972
|
calloutBoxElement.style.marginBottom = `${ARROW_HEIGHT}px`;
|
|
@@ -17238,21 +17253,6 @@ const generateSvgWithoutArrow = (width, height) => {
|
|
|
17238
17253
|
/>
|
|
17239
17254
|
</svg>`;
|
|
17240
17255
|
};
|
|
17241
|
-
const dispatchCalloutCustomElement = (anchorElement, customEvent) => {
|
|
17242
|
-
let targetElement;
|
|
17243
|
-
const visualSelector = anchorElement.getAttribute("data-visual-selector");
|
|
17244
|
-
if (visualSelector) {
|
|
17245
|
-
const visualElement = anchorElement.querySelector(visualSelector);
|
|
17246
|
-
if (visualElement) {
|
|
17247
|
-
targetElement = visualElement;
|
|
17248
|
-
}
|
|
17249
|
-
} else {
|
|
17250
|
-
targetElement = anchorElement;
|
|
17251
|
-
}
|
|
17252
|
-
|
|
17253
|
-
// console.log("dispatch on", targetElement, "event", customEvent);
|
|
17254
|
-
targetElement.dispatchEvent(customEvent);
|
|
17255
|
-
};
|
|
17256
17256
|
|
|
17257
17257
|
/**
|
|
17258
17258
|
* Creates a live mirror of a source DOM element that automatically stays in sync.
|
|
@@ -18709,6 +18709,9 @@ const installCustomConstraintValidation = (
|
|
|
18709
18709
|
return element;
|
|
18710
18710
|
})();
|
|
18711
18711
|
const onmousedown = (e) => {
|
|
18712
|
+
if (e.button !== 0) {
|
|
18713
|
+
return;
|
|
18714
|
+
}
|
|
18712
18715
|
if (!validationInterface.validationMessage) {
|
|
18713
18716
|
return;
|
|
18714
18717
|
}
|
|
@@ -22514,9 +22517,9 @@ const useUIState = (uiStateController) => {
|
|
|
22514
22517
|
installImportMetaCssBuild(import.meta);const css$x = /* css */`
|
|
22515
22518
|
@layer navi {
|
|
22516
22519
|
.navi_button {
|
|
22520
|
+
--button-border-radius: 2px;
|
|
22517
22521
|
--button-outline-width: 1px;
|
|
22518
22522
|
--button-border-width: 1px;
|
|
22519
|
-
--button-border-radius: 2px;
|
|
22520
22523
|
/* Global padding defaults — override these to change all button paddings. */
|
|
22521
22524
|
/* Use --button-padding, --button-padding-x, --button-padding-y for per-button overrides. */
|
|
22522
22525
|
--button-padding-x-default: 6px;
|
|
@@ -22580,25 +22583,22 @@ installImportMetaCssBuild(import.meta);const css$x = /* css */`
|
|
|
22580
22583
|
}
|
|
22581
22584
|
|
|
22582
22585
|
.navi_button {
|
|
22583
|
-
/*
|
|
22584
|
-
--x-button-outline-width: var(--button-outline-width)
|
|
22585
|
-
|
|
22586
|
-
--x-button-
|
|
22587
|
-
--x-button-outer-width: calc(
|
|
22588
|
-
var(--x-button-border-width) + var(--x-button-outline-width)
|
|
22589
|
-
);
|
|
22590
|
-
--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));
|
|
22591
22590
|
--x-button-border-color: var(--button-border-color);
|
|
22592
22591
|
--x-button-background: var(--button-background);
|
|
22593
22592
|
--x-button-background-color: var(--button-background-color);
|
|
22594
22593
|
--x-button-color: var(--button-color);
|
|
22595
22594
|
--x-button-cursor: var(--button-cursor);
|
|
22595
|
+
|
|
22596
22596
|
box-sizing: border-box;
|
|
22597
22597
|
aspect-ratio: inherit;
|
|
22598
22598
|
padding: 0;
|
|
22599
22599
|
background: none;
|
|
22600
22600
|
border: none;
|
|
22601
|
-
border-radius: var(--
|
|
22601
|
+
border-radius: var(--button-border-radius);
|
|
22602
22602
|
outline: none;
|
|
22603
22603
|
cursor: var(--x-button-cursor);
|
|
22604
22604
|
-webkit-tap-highlight-color: transparent;
|
|
@@ -22658,15 +22658,13 @@ installImportMetaCssBuild(import.meta);const css$x = /* css */`
|
|
|
22658
22658
|
--x-button-background-color,
|
|
22659
22659
|
var(--x-button-background)
|
|
22660
22660
|
);
|
|
22661
|
-
|
|
22662
|
-
border-width: var(--x-button-outer-width);
|
|
22661
|
+
border-width: var(--button-border-width);
|
|
22663
22662
|
border-style: solid;
|
|
22664
|
-
border-color:
|
|
22665
|
-
border-radius: var(--
|
|
22666
|
-
outline-width: var(--x-button-
|
|
22667
|
-
outline-
|
|
22668
|
-
outline-
|
|
22669
|
-
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);
|
|
22670
22668
|
transition-property: transform;
|
|
22671
22669
|
transition-duration: 0.15s;
|
|
22672
22670
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -22727,12 +22725,10 @@ installImportMetaCssBuild(import.meta);const css$x = /* css */`
|
|
|
22727
22725
|
}
|
|
22728
22726
|
/* Focus */
|
|
22729
22727
|
&[data-focus-visible] {
|
|
22730
|
-
--x-button-border-color:
|
|
22731
|
-
|
|
22732
|
-
&[data-focus-visible] {
|
|
22728
|
+
--x-button-border-color: transparent;
|
|
22729
|
+
|
|
22733
22730
|
.navi_button_content {
|
|
22734
|
-
outline-
|
|
22735
|
-
outline-offset: calc(-1 * var(--x-button-outer-width));
|
|
22731
|
+
outline-style: solid;
|
|
22736
22732
|
}
|
|
22737
22733
|
}
|
|
22738
22734
|
/* Disabled */
|
|
@@ -28152,7 +28148,6 @@ const ListWithPopover = props => {
|
|
|
28152
28148
|
left,
|
|
28153
28149
|
top
|
|
28154
28150
|
} = pickPositionRelativeTo(listContainerEl, anchor, {
|
|
28155
|
-
positionTry: "bottom",
|
|
28156
28151
|
minLeft
|
|
28157
28152
|
});
|
|
28158
28153
|
listContainerEl.style.top = `${top}px`;
|
|
@@ -28942,7 +28937,6 @@ const css$k = /* css */`
|
|
|
28942
28937
|
--border-radius: 2px;
|
|
28943
28938
|
--border-width: 1px;
|
|
28944
28939
|
--outline-width: 1px;
|
|
28945
|
-
--outer-width: calc(var(--border-width) + var(--outline-width));
|
|
28946
28940
|
--font-size: 14px;
|
|
28947
28941
|
|
|
28948
28942
|
/* Default */
|
|
@@ -28986,6 +28980,16 @@ const css$k = /* css */`
|
|
|
28986
28980
|
}
|
|
28987
28981
|
|
|
28988
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
|
+
|
|
28989
28993
|
position: relative;
|
|
28990
28994
|
box-sizing: border-box;
|
|
28991
28995
|
width: fit-content;
|
|
@@ -28994,18 +28998,6 @@ const css$k = /* css */`
|
|
|
28994
28998
|
border-radius: inherit;
|
|
28995
28999
|
cursor: inherit;
|
|
28996
29000
|
|
|
28997
|
-
--left-slot-size: 0px;
|
|
28998
|
-
--right-slot-size: 0px;
|
|
28999
|
-
--x-outline-width: var(--outline-width);
|
|
29000
|
-
--x-border-radius: var(--border-radius);
|
|
29001
|
-
--x-border-width: var(--border-width);
|
|
29002
|
-
--x-outer-width: calc(var(--x-border-width) + var(--x-outline-width));
|
|
29003
|
-
--x-outline-color: var(--outline-color);
|
|
29004
|
-
--x-border-color: var(--border-color);
|
|
29005
|
-
--x-background-color: var(--background-color);
|
|
29006
|
-
--x-color: var(--color);
|
|
29007
|
-
--x-placeholder-color: var(--placeholder-color);
|
|
29008
|
-
|
|
29009
29001
|
--x-padding-top-base: var(
|
|
29010
29002
|
--padding-top,
|
|
29011
29003
|
var(--padding-y, var(--padding, 1px))
|
|
@@ -29033,15 +29025,13 @@ const css$k = /* css */`
|
|
|
29033
29025
|
color: var(--x-color);
|
|
29034
29026
|
font-size: var(--font-size);
|
|
29035
29027
|
background-color: var(--x-background-color);
|
|
29036
|
-
border-width: var(--
|
|
29037
|
-
border-width: var(--x-outer-width);
|
|
29028
|
+
border-width: var(--border-width);
|
|
29038
29029
|
border-style: solid;
|
|
29039
|
-
border-color:
|
|
29040
|
-
border-radius: var(--
|
|
29041
|
-
outline-width: var(--x-
|
|
29042
|
-
outline-
|
|
29043
|
-
outline-
|
|
29044
|
-
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);
|
|
29045
29035
|
|
|
29046
29036
|
&[type="search"] {
|
|
29047
29037
|
-webkit-appearance: textfield;
|
|
@@ -29121,12 +29111,10 @@ const css$k = /* css */`
|
|
|
29121
29111
|
&[data-focus],
|
|
29122
29112
|
&[data-focus-visible] {
|
|
29123
29113
|
--x-background-color: var(--background-color-focus);
|
|
29124
|
-
--x-border-color:
|
|
29114
|
+
--x-border-color: transparent;
|
|
29125
29115
|
|
|
29126
29116
|
.navi_native_input {
|
|
29127
|
-
outline-
|
|
29128
|
-
outline-offset: calc(-1 * var(--x-outer-width));
|
|
29129
|
-
--x-border-color: var(--x-outline-color);
|
|
29117
|
+
outline-style: solid;
|
|
29130
29118
|
}
|
|
29131
29119
|
}
|
|
29132
29120
|
/* Disabled */
|
|
@@ -29421,7 +29409,13 @@ const InputSlot = ({
|
|
|
29421
29409
|
flex: true,
|
|
29422
29410
|
alignY: "center",
|
|
29423
29411
|
onMouseDown: e => {
|
|
29424
|
-
|
|
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
|
+
}
|
|
29425
29419
|
},
|
|
29426
29420
|
onClick: e => {
|
|
29427
29421
|
if (readOnly || disabled) {
|
|
@@ -30609,12 +30603,12 @@ const Dialog = props => {
|
|
|
30609
30603
|
} = props;
|
|
30610
30604
|
const defaultRef = useRef();
|
|
30611
30605
|
const ref = rest.ref || defaultRef;
|
|
30612
|
-
const
|
|
30606
|
+
const debugPopup = useDebugPopup();
|
|
30613
30607
|
const debugFocus = useDebugFocus();
|
|
30614
30608
|
const openedRef = useRef(false);
|
|
30615
30609
|
const [addCleanup, cleanup] = useCleanup();
|
|
30616
30610
|
const open = e => {
|
|
30617
|
-
|
|
30611
|
+
debugPopup(`"${e.type}" on ${getElementSignature(e.target)} -> openDialog`);
|
|
30618
30612
|
const dialogEl = ref.current;
|
|
30619
30613
|
dialogEl.showModal();
|
|
30620
30614
|
const firstFocusable = findFocusable(dialogEl);
|
|
@@ -30633,7 +30627,7 @@ const Dialog = props => {
|
|
|
30633
30627
|
});
|
|
30634
30628
|
};
|
|
30635
30629
|
const close = e => {
|
|
30636
|
-
|
|
30630
|
+
debugPopup(`"${e.type}" on ${getElementSignature(e.target)} -> closeDialog`);
|
|
30637
30631
|
const dialogEl = ref.current;
|
|
30638
30632
|
dialogEl.close();
|
|
30639
30633
|
cleanup();
|
|
@@ -30733,14 +30727,17 @@ const Popover = props => {
|
|
|
30733
30727
|
pointerTrap,
|
|
30734
30728
|
focusTrap,
|
|
30735
30729
|
children,
|
|
30736
|
-
|
|
30730
|
+
positionX,
|
|
30731
|
+
positionY,
|
|
30732
|
+
positionXFixed,
|
|
30733
|
+
positionYFixed,
|
|
30737
30734
|
...rest
|
|
30738
30735
|
} = props;
|
|
30739
30736
|
const defaultRef = useRef();
|
|
30740
30737
|
const ref = rest.ref || defaultRef;
|
|
30741
30738
|
const defaultId = useId();
|
|
30742
30739
|
const id = rest.id || defaultId;
|
|
30743
|
-
const
|
|
30740
|
+
const debugPopup = useDebugPopup();
|
|
30744
30741
|
const debugFocus = useDebugFocus();
|
|
30745
30742
|
const [opened, setOpened] = useState(false);
|
|
30746
30743
|
const openedRef = useRef(opened);
|
|
@@ -30749,7 +30746,7 @@ const Popover = props => {
|
|
|
30749
30746
|
const open = (e, {
|
|
30750
30747
|
anchor
|
|
30751
30748
|
}) => {
|
|
30752
|
-
|
|
30749
|
+
debugPopup(`openPopover("${e.type}")`);
|
|
30753
30750
|
const popoverEl = ref.current;
|
|
30754
30751
|
popoverEl.showPopover();
|
|
30755
30752
|
const firstFocusable = findFocusable(popoverEl);
|
|
@@ -30761,27 +30758,27 @@ const Popover = props => {
|
|
|
30761
30758
|
}
|
|
30762
30759
|
const effectiveAnchor = anchor || document.documentElement;
|
|
30763
30760
|
const positionPopover = positionEvent => {
|
|
30764
|
-
|
|
30765
|
-
|
|
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`);
|
|
30766
30767
|
const minLeft = 1;
|
|
30767
|
-
const
|
|
30768
|
+
const effectivePositionX = anchor ? positionX : "center";
|
|
30768
30769
|
const {
|
|
30769
30770
|
left,
|
|
30770
30771
|
top
|
|
30771
30772
|
} = pickPositionRelativeTo(popoverEl, effectiveAnchor, {
|
|
30772
|
-
|
|
30773
|
+
positionX: effectivePositionX,
|
|
30774
|
+
positionY,
|
|
30775
|
+
positionXFixed,
|
|
30776
|
+
positionYFixed,
|
|
30773
30777
|
minLeft
|
|
30774
30778
|
});
|
|
30779
|
+
debugPopup(`positionPopover("${positionEvent.type}") -> left: ${left}, top: ${top}`);
|
|
30775
30780
|
popoverEl.style.top = `${top}px`;
|
|
30776
|
-
|
|
30777
|
-
const maxWidth = parseFloat(getComputedStyle(popoverEl).maxWidth);
|
|
30778
|
-
if (!isNaN(maxWidth) && popoverRect.width >= maxWidth - 1) {
|
|
30779
|
-
const viewportWidth = document.documentElement.clientWidth;
|
|
30780
|
-
const centeredLeft = (viewportWidth - popoverRect.width) / 2;
|
|
30781
|
-
popoverEl.style.left = `${Math.max(centeredLeft, minLeft)}px`;
|
|
30782
|
-
} else {
|
|
30783
|
-
popoverEl.style.left = `${Math.max(left, minLeft)}px`;
|
|
30784
|
-
}
|
|
30781
|
+
popoverEl.style.left = `${Math.max(left, minLeft)}px`;
|
|
30785
30782
|
};
|
|
30786
30783
|
if (scrollTrap) {
|
|
30787
30784
|
addCleanup(trapScrollInside(popoverEl));
|
|
@@ -30813,7 +30810,7 @@ const Popover = props => {
|
|
|
30813
30810
|
});
|
|
30814
30811
|
};
|
|
30815
30812
|
const close = e => {
|
|
30816
|
-
|
|
30813
|
+
debugPopup(`closePopover("${e.type}")`);
|
|
30817
30814
|
const popoverEl = ref.current;
|
|
30818
30815
|
popoverEl.hidePopover();
|
|
30819
30816
|
cleanup();
|
|
@@ -30867,6 +30864,7 @@ const Popover = props => {
|
|
|
30867
30864
|
...rest,
|
|
30868
30865
|
ref: ref,
|
|
30869
30866
|
baseClassName: "navi_popover",
|
|
30867
|
+
pseudoClasses: PopoverPseudoClasses,
|
|
30870
30868
|
onnavi_popover_request_open: e => {
|
|
30871
30869
|
const {
|
|
30872
30870
|
event = e,
|
|
@@ -30886,6 +30884,7 @@ const Popover = props => {
|
|
|
30886
30884
|
})]
|
|
30887
30885
|
});
|
|
30888
30886
|
};
|
|
30887
|
+
const PopoverPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":focus-within", ":read-only", ":disabled"];
|
|
30889
30888
|
const requestPopoverOpen = (popoverElement, {
|
|
30890
30889
|
event,
|
|
30891
30890
|
anchor
|
|
@@ -30907,11 +30906,12 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
|
|
|
30907
30906
|
@layer navi {
|
|
30908
30907
|
.navi_select {
|
|
30909
30908
|
--select-border-radius: 2px;
|
|
30910
|
-
--select-border-width: 1px;
|
|
30911
30909
|
--select-outline-width: 1px;
|
|
30910
|
+
--select-border-width: 1px;
|
|
30912
30911
|
--select-font-size: 14px;
|
|
30913
30912
|
--select-padding-x-default: 8px;
|
|
30914
30913
|
--select-padding-y-default: 5px;
|
|
30914
|
+
--select-outline-color: var(--navi-focus-outline-color);
|
|
30915
30915
|
--select-border-color: light-dark(#767676, #8e8e93);
|
|
30916
30916
|
--select-background-color: white;
|
|
30917
30917
|
--select-color: currentColor;
|
|
@@ -30934,60 +30934,66 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
|
|
|
30934
30934
|
}
|
|
30935
30935
|
|
|
30936
30936
|
.navi_select {
|
|
30937
|
-
|
|
30938
|
-
|
|
30939
|
-
|
|
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(
|
|
30940
30945
|
--select-padding-top,
|
|
30941
30946
|
var(--select-padding-y, var(--select-padding-y-default))
|
|
30942
30947
|
);
|
|
30943
|
-
padding-right: var(
|
|
30948
|
+
--x-select-padding-right: var(
|
|
30944
30949
|
--select-padding-right,
|
|
30945
30950
|
var(--select-padding-x, var(--select-padding-x-default))
|
|
30946
30951
|
);
|
|
30947
|
-
padding-
|
|
30948
|
-
--select-padding-bottom,
|
|
30949
|
-
var(--select-padding-y, var(--select-padding-y-default))
|
|
30950
|
-
);
|
|
30951
|
-
padding-left: var(
|
|
30952
|
+
--x-select-padding-left: var(
|
|
30952
30953
|
--select-padding-left,
|
|
30953
30954
|
var(--select-padding-x, var(--select-padding-x-default))
|
|
30954
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);
|
|
30955
30967
|
color: var(--select-color);
|
|
30956
30968
|
font-size: var(--select-font-size);
|
|
30957
30969
|
text-align: inherit; /* override browser defaults on button which is center */
|
|
30958
30970
|
white-space: nowrap; /* Prevent icon from going next line */
|
|
30959
|
-
background-color: var(--select-background-color);
|
|
30960
|
-
border: var(--select-border-width)
|
|
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);
|
|
30961
30975
|
border-radius: var(--select-border-radius);
|
|
30962
|
-
outline: var(--select-outline-width)
|
|
30963
|
-
outline-
|
|
30976
|
+
outline-width: var(--x-select-outline-width);
|
|
30977
|
+
outline-color: var(--select-outline-color);
|
|
30978
|
+
outline-offset: var(--x-select-outline-offset);
|
|
30964
30979
|
user-select: none;
|
|
30965
30980
|
|
|
30966
|
-
--x-select-outline-width-focus-visible: calc(
|
|
30967
|
-
var(--select-border-width) + var(--select-outline-width)
|
|
30968
|
-
);
|
|
30969
|
-
--x-select-outline-offset-focus-visible: calc(
|
|
30970
|
-
-1 * (var(--select-border-width) + var(--select-outline-width))
|
|
30971
|
-
);
|
|
30972
|
-
|
|
30973
30981
|
&[data-hover] {
|
|
30974
|
-
background-color: var(--select-background-color-hover);
|
|
30975
|
-
|
|
30982
|
+
--x-select-background-color: var(--select-background-color-hover);
|
|
30983
|
+
--x-select-border-color: var(--select-border-color-hover);
|
|
30976
30984
|
}
|
|
30977
30985
|
|
|
30978
30986
|
&[data-focus-visible] {
|
|
30979
|
-
|
|
30980
|
-
outline-
|
|
30981
|
-
outline-offset: var(--x-select-outline-offset-focus-visible);
|
|
30987
|
+
--x-select-border-color: transparent;
|
|
30988
|
+
outline-style: solid;
|
|
30982
30989
|
}
|
|
30983
30990
|
|
|
30984
30991
|
&[data-disabled] {
|
|
30985
30992
|
opacity: 0.5;
|
|
30986
30993
|
cursor: default;
|
|
30987
30994
|
}
|
|
30988
|
-
|
|
30989
|
-
|
|
30990
|
-
--list-border-radius: 0;
|
|
30995
|
+
&[data-callout] {
|
|
30996
|
+
--x-select-border-color: var(--callout-color);
|
|
30991
30997
|
}
|
|
30992
30998
|
|
|
30993
30999
|
.navi_select_trigger_text {
|
|
@@ -31015,19 +31021,21 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
|
|
|
31015
31021
|
}
|
|
31016
31022
|
}
|
|
31017
31023
|
.navi_select_trigger_icon {
|
|
31018
|
-
margin-left: 6px;
|
|
31019
31024
|
flex-shrink: 0;
|
|
31020
31025
|
opacity: 0.6;
|
|
31021
31026
|
}
|
|
31022
31027
|
|
|
31023
31028
|
/* popover */
|
|
31024
31029
|
&[aria-haspopup="listbox"] {
|
|
31025
|
-
|
|
31026
|
-
|
|
31027
|
-
|
|
31028
|
-
|
|
31029
|
-
|
|
31030
|
-
|
|
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%;
|
|
31031
31039
|
}
|
|
31032
31040
|
}
|
|
31033
31041
|
|
|
@@ -31036,18 +31044,79 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
|
|
|
31036
31044
|
inset: unset;
|
|
31037
31045
|
min-width: var(--anchor-width, 0px);
|
|
31038
31046
|
max-width: 95vw;
|
|
31047
|
+
/* max-height covers the placeholder + list; the list scrolls internally */
|
|
31039
31048
|
max-height: 95dvh;
|
|
31040
31049
|
margin: 0;
|
|
31041
31050
|
padding: 0;
|
|
31042
|
-
background:
|
|
31043
|
-
border:
|
|
31044
|
-
border-
|
|
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);
|
|
31045
31059
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
|
|
31046
31060
|
cursor: default; /* Reset pointer cursor within the select */
|
|
31047
|
-
overflow:
|
|
31061
|
+
overflow: hidden;
|
|
31048
31062
|
overscroll-behavior: none;
|
|
31049
31063
|
|
|
31050
|
-
|
|
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 {
|
|
31051
31120
|
display: flex;
|
|
31052
31121
|
flex-direction: column;
|
|
31053
31122
|
}
|
|
@@ -31057,17 +31126,15 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
|
|
|
31057
31126
|
/* dialog */
|
|
31058
31127
|
&[aria-haspopup="dialog"] {
|
|
31059
31128
|
.navi_list_container {
|
|
31129
|
+
width: 100%;
|
|
31060
31130
|
--list-max-height: none;
|
|
31061
|
-
|
|
31131
|
+
/* Handled by the dialog */
|
|
31132
|
+
border: none;
|
|
31133
|
+
border-radius: 0;
|
|
31134
|
+
outline: none;
|
|
31062
31135
|
|
|
31063
|
-
|
|
31064
|
-
|
|
31065
|
-
&:has(.navi_list_container[data-focus-visible]) {
|
|
31066
|
-
outline-width: var(--x-select-outline-width-focus-visible);
|
|
31067
|
-
outline-color: var(--navi-focus-outline-color);
|
|
31068
|
-
outline-offset: var(--x-select-outline-offset-focus-visible);
|
|
31069
|
-
.navi_list_container {
|
|
31070
|
-
outline: none;
|
|
31136
|
+
.navi_list {
|
|
31137
|
+
width: 100%;
|
|
31071
31138
|
}
|
|
31072
31139
|
}
|
|
31073
31140
|
|
|
@@ -31075,9 +31142,12 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
|
|
|
31075
31142
|
max-height: 95dvh;
|
|
31076
31143
|
margin: auto;
|
|
31077
31144
|
padding: 0;
|
|
31078
|
-
background:
|
|
31079
|
-
border:
|
|
31080
|
-
border-radius:
|
|
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);
|
|
31081
31151
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
|
|
31082
31152
|
cursor: default; /* Reset pointer cursor within the select */
|
|
31083
31153
|
|
|
@@ -31090,6 +31160,14 @@ installImportMetaCssBuild(import.meta);const css$f = /* css */`
|
|
|
31090
31160
|
background: rgba(0, 0, 0, 0.4);
|
|
31091
31161
|
}
|
|
31092
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
|
+
}
|
|
31093
31171
|
}
|
|
31094
31172
|
}
|
|
31095
31173
|
`;
|
|
@@ -31133,6 +31211,7 @@ const Select = props => {
|
|
|
31133
31211
|
return jsx(ParentUIStateControllerContext.Provider, {
|
|
31134
31212
|
value: uiStateController,
|
|
31135
31213
|
children: jsx(SelectDispatcher, {
|
|
31214
|
+
trigger: jsx(SelectTrigger, {}),
|
|
31136
31215
|
...props,
|
|
31137
31216
|
ref: ref,
|
|
31138
31217
|
value: value
|
|
@@ -31161,7 +31240,7 @@ const SelectDispatcher = props => {
|
|
|
31161
31240
|
};
|
|
31162
31241
|
const SelectUI = props => {
|
|
31163
31242
|
import.meta.css = [css$f, "@jsenv/navi/src/field/select.jsx"];
|
|
31164
|
-
|
|
31243
|
+
const {
|
|
31165
31244
|
placeholder = "Select…",
|
|
31166
31245
|
trigger,
|
|
31167
31246
|
name,
|
|
@@ -31192,9 +31271,6 @@ const SelectUI = props => {
|
|
|
31192
31271
|
useAutoFocus(ref, autoFocus, {
|
|
31193
31272
|
preventScroll: autoFocusPreventScroll
|
|
31194
31273
|
});
|
|
31195
|
-
if (trigger === undefined) {
|
|
31196
|
-
trigger = jsx(SelectTrigger, {});
|
|
31197
|
-
}
|
|
31198
31274
|
return jsxs(Box, {
|
|
31199
31275
|
as: "button",
|
|
31200
31276
|
type: "button",
|
|
@@ -31237,6 +31313,7 @@ const SelectUI = props => {
|
|
|
31237
31313
|
const SelectPlaceholderContext = createContext();
|
|
31238
31314
|
const SelectValueContext = createContext(null);
|
|
31239
31315
|
const SelectStyleCSSVars = {
|
|
31316
|
+
"outlineWidth": "--select-outline-width",
|
|
31240
31317
|
"borderWidth": "--select-border-width",
|
|
31241
31318
|
"borderRadius": "--select-border-radius",
|
|
31242
31319
|
"paddingX": "--select-padding-x",
|
|
@@ -31274,14 +31351,16 @@ const SelectStyleCSSVars = {
|
|
|
31274
31351
|
color: "--select-color-disabled"
|
|
31275
31352
|
}
|
|
31276
31353
|
};
|
|
31277
|
-
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"];
|
|
31278
31355
|
const SelectPseudoElements = ["::-navi-loader"];
|
|
31279
31356
|
const SelectTrigger = () => {
|
|
31280
31357
|
const placeholder = useContext(SelectPlaceholderContext);
|
|
31281
31358
|
const value = useContext(SelectValueContext);
|
|
31282
31359
|
const hasValue = value !== null && value !== undefined && value !== "";
|
|
31283
31360
|
const isPlaceholder = !hasValue;
|
|
31284
|
-
return jsxs(
|
|
31361
|
+
return jsxs(Box, {
|
|
31362
|
+
flex: true,
|
|
31363
|
+
spacing: "s",
|
|
31285
31364
|
children: [jsxs("span", {
|
|
31286
31365
|
className: "navi_select_trigger_text",
|
|
31287
31366
|
children: [jsx("span", {
|
|
@@ -31307,13 +31386,13 @@ const SelectWithPopover = props => {
|
|
|
31307
31386
|
disabled,
|
|
31308
31387
|
onKeyDown,
|
|
31309
31388
|
children,
|
|
31310
|
-
positionTry,
|
|
31311
31389
|
pointerTrap,
|
|
31312
31390
|
scrollTrap = true,
|
|
31313
31391
|
focusTrap = true,
|
|
31314
31392
|
...rest
|
|
31315
31393
|
} = props;
|
|
31316
31394
|
const debugFocus = useDebugFocus();
|
|
31395
|
+
const debugPopup = useDebugPopup();
|
|
31317
31396
|
const popoverRef = useRef(null);
|
|
31318
31397
|
const popoverId = useId();
|
|
31319
31398
|
const [expanded, setExpanded] = useState(false);
|
|
@@ -31328,12 +31407,21 @@ const SelectWithPopover = props => {
|
|
|
31328
31407
|
setExpanded(false);
|
|
31329
31408
|
};
|
|
31330
31409
|
const requestOpen = e => {
|
|
31410
|
+
// scroll select into view when opening it
|
|
31411
|
+
ref.current.scrollIntoView({
|
|
31412
|
+
block: "nearest"
|
|
31413
|
+
});
|
|
31331
31414
|
return requestPopoverOpen(popoverRef.current, {
|
|
31332
31415
|
event: e,
|
|
31333
31416
|
anchor: ref.current
|
|
31334
31417
|
});
|
|
31335
31418
|
};
|
|
31419
|
+
const [shouldIgnoreThatClick, disableClickFor] = useIgnoreClickForMousedown();
|
|
31336
31420
|
const requestClose = (e = new CustomEvent("programmatic")) => {
|
|
31421
|
+
if (e.type === "mousedown") {
|
|
31422
|
+
debugPopup(formatEventSideEffect(e, `disable click`));
|
|
31423
|
+
disableClickFor(e);
|
|
31424
|
+
}
|
|
31337
31425
|
return requestPopoverClose(popoverRef.current, {
|
|
31338
31426
|
event: e
|
|
31339
31427
|
});
|
|
@@ -31345,7 +31433,6 @@ const SelectWithPopover = props => {
|
|
|
31345
31433
|
preventScroll: true
|
|
31346
31434
|
});
|
|
31347
31435
|
};
|
|
31348
|
-
const [shouldIgnoreThatClick, disableClickFor] = useIgnoreClickForMousedown();
|
|
31349
31436
|
return jsx(SelectDispatcher, {
|
|
31350
31437
|
disabled: disabled,
|
|
31351
31438
|
"aria-haspopup": "listbox",
|
|
@@ -31372,6 +31459,7 @@ const SelectWithPopover = props => {
|
|
|
31372
31459
|
return;
|
|
31373
31460
|
}
|
|
31374
31461
|
if (shouldIgnoreThatClick) {
|
|
31462
|
+
debugPopup(formatEventSideEffect(e, `ignore click`));
|
|
31375
31463
|
return;
|
|
31376
31464
|
}
|
|
31377
31465
|
// When a label is clicked it transfers focus to the select
|
|
@@ -31393,8 +31481,8 @@ const SelectWithPopover = props => {
|
|
|
31393
31481
|
// space can open the popover we don't want space to propagate to the select otherwise it would open it back immediatly
|
|
31394
31482
|
event.stopPropagation();
|
|
31395
31483
|
}
|
|
31396
|
-
requestClose(
|
|
31397
|
-
moveFocusToSelect(
|
|
31484
|
+
requestClose(event);
|
|
31485
|
+
moveFocusToSelect(event);
|
|
31398
31486
|
},
|
|
31399
31487
|
onFocusOut: e => {
|
|
31400
31488
|
// Close when focus leaves the select entirely (not just moving between internal elements).
|
|
@@ -31432,7 +31520,7 @@ const SelectWithPopover = props => {
|
|
|
31432
31520
|
}, onKeyDown),
|
|
31433
31521
|
ref: ref,
|
|
31434
31522
|
mode: "ui",
|
|
31435
|
-
children:
|
|
31523
|
+
children: jsxs(Popover, {
|
|
31436
31524
|
ref: popoverRef,
|
|
31437
31525
|
className: "navi_select_popover",
|
|
31438
31526
|
onMouseDown: e => {
|
|
@@ -31441,7 +31529,6 @@ const SelectWithPopover = props => {
|
|
|
31441
31529
|
}
|
|
31442
31530
|
// mousedown inside popover should not bubble to the select (would re-open it if that mousedown closes it)
|
|
31443
31531
|
e.stopPropagation();
|
|
31444
|
-
disableClickFor(e);
|
|
31445
31532
|
},
|
|
31446
31533
|
onnavi_popover_open: e => {
|
|
31447
31534
|
onOpen();
|
|
@@ -31452,17 +31539,27 @@ const SelectWithPopover = props => {
|
|
|
31452
31539
|
event = e
|
|
31453
31540
|
} = e.detail;
|
|
31454
31541
|
if (event.type === "focusout") ; else {
|
|
31455
|
-
moveFocusToSelect(
|
|
31542
|
+
moveFocusToSelect(event);
|
|
31456
31543
|
}
|
|
31457
31544
|
},
|
|
31458
|
-
|
|
31545
|
+
positionX: "left-aligned",
|
|
31546
|
+
positionY: "below-overlap",
|
|
31459
31547
|
scrollTrap: scrollTrap,
|
|
31460
31548
|
pointerTrap: pointerTrap,
|
|
31461
31549
|
focusTrap: focusTrap,
|
|
31462
|
-
children: jsx(
|
|
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, {
|
|
31463
31560
|
value: requestClose,
|
|
31464
31561
|
children: children
|
|
31465
|
-
})
|
|
31562
|
+
})]
|
|
31466
31563
|
})
|
|
31467
31564
|
});
|
|
31468
31565
|
};
|
|
@@ -31478,6 +31575,7 @@ const SelectWithDialog = props => {
|
|
|
31478
31575
|
...rest
|
|
31479
31576
|
} = props;
|
|
31480
31577
|
const debugFocus = useDebugFocus();
|
|
31578
|
+
const debugPopup = useDebugPopup();
|
|
31481
31579
|
const dialogRef = useRef(null);
|
|
31482
31580
|
const dialogId = useId();
|
|
31483
31581
|
const [expanded, setExpanded] = useState(false);
|
|
@@ -31496,7 +31594,12 @@ const SelectWithDialog = props => {
|
|
|
31496
31594
|
event: e
|
|
31497
31595
|
});
|
|
31498
31596
|
};
|
|
31597
|
+
const [shouldIgnore, disableClickFor] = useIgnoreClickForMousedown();
|
|
31499
31598
|
const requestClose = (e = new CustomEvent("programmatic")) => {
|
|
31599
|
+
if (e.type === "mousedown") {
|
|
31600
|
+
debugPopup(formatEventSideEffect(e, `disable click`));
|
|
31601
|
+
disableClickFor(e);
|
|
31602
|
+
}
|
|
31500
31603
|
return requestDialogClose(dialogRef.current, {
|
|
31501
31604
|
event: e
|
|
31502
31605
|
});
|
|
@@ -31507,7 +31610,6 @@ const SelectWithDialog = props => {
|
|
|
31507
31610
|
preventScroll: true
|
|
31508
31611
|
});
|
|
31509
31612
|
};
|
|
31510
|
-
const [shouldIgnoreThatClick, disableClickFor] = useIgnoreClickForMousedown();
|
|
31511
31613
|
return jsx(SelectDispatcher, {
|
|
31512
31614
|
disabled: disabled,
|
|
31513
31615
|
"aria-haspopup": "dialog",
|
|
@@ -31533,7 +31635,8 @@ const SelectWithDialog = props => {
|
|
|
31533
31635
|
// click triggered by enter won't open the dialog
|
|
31534
31636
|
return;
|
|
31535
31637
|
}
|
|
31536
|
-
if (
|
|
31638
|
+
if (shouldIgnore) {
|
|
31639
|
+
debugPopup(formatEventSideEffect(e, `ignore click`));
|
|
31537
31640
|
// mousedown on the select already handled open/close; ignore this click
|
|
31538
31641
|
// to avoid toggling the dialog again on mouseup
|
|
31539
31642
|
return;
|
|
@@ -31549,7 +31652,7 @@ const SelectWithDialog = props => {
|
|
|
31549
31652
|
// space can open the dialog, we don't want space to propagate to the select otherwise it would open it back immediately
|
|
31550
31653
|
event.stopPropagation();
|
|
31551
31654
|
}
|
|
31552
|
-
requestClose(
|
|
31655
|
+
requestClose(event);
|
|
31553
31656
|
},
|
|
31554
31657
|
...rest,
|
|
31555
31658
|
onKeyDown: shortcutsViaOnKeyDown({
|
|
@@ -31593,7 +31696,6 @@ const SelectWithDialog = props => {
|
|
|
31593
31696
|
}
|
|
31594
31697
|
// mousedown inside dialog should not bubble to the select (would re-open it if that mousedown closes it)
|
|
31595
31698
|
e.stopPropagation();
|
|
31596
|
-
disableClickFor(e);
|
|
31597
31699
|
},
|
|
31598
31700
|
scrollTrap: scrollTrap,
|
|
31599
31701
|
pointerTrap: pointerTrap,
|