@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.
- package/dist/jsenv_navi.js +313 -197
- package/dist/jsenv_navi.js.map +44 -41
- 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) {
|
|
@@ -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
|
-
|
|
16596
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16872
|
-
|
|
16873
|
-
|
|
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
|
|
16878
|
-
if (
|
|
16879
|
-
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);
|
|
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 =
|
|
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 (
|
|
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
|
-
/*
|
|
22571
|
-
--x-button-outline-width: var(--button-outline-width)
|
|
22572
|
-
|
|
22573
|
-
--x-button-
|
|
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(--
|
|
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:
|
|
22652
|
-
border-radius: var(--
|
|
22653
|
-
outline-width: var(--x-button-
|
|
22654
|
-
outline-
|
|
22655
|
-
outline-
|
|
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:
|
|
22718
|
-
|
|
22719
|
-
&[data-focus-visible] {
|
|
22728
|
+
--x-button-border-color: transparent;
|
|
22729
|
+
|
|
22720
22730
|
.navi_button_content {
|
|
22721
|
-
outline-
|
|
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(--
|
|
29023
|
-
border-width: var(--x-outer-width);
|
|
29028
|
+
border-width: var(--border-width);
|
|
29024
29029
|
border-style: solid;
|
|
29025
|
-
border-color:
|
|
29026
|
-
border-radius: var(--
|
|
29027
|
-
outline-width: var(--x-
|
|
29028
|
-
outline-
|
|
29029
|
-
outline-
|
|
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:
|
|
29114
|
+
--x-border-color: transparent;
|
|
29111
29115
|
|
|
29112
29116
|
.navi_native_input {
|
|
29113
|
-
outline-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
30751
|
-
|
|
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
|
|
30768
|
+
const effectivePositionX = anchor ? positionX : "center";
|
|
30754
30769
|
const {
|
|
30755
30770
|
left,
|
|
30756
30771
|
top
|
|
30757
30772
|
} = pickPositionRelativeTo(popoverEl, effectiveAnchor, {
|
|
30758
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
30924
|
-
|
|
30925
|
-
|
|
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-
|
|
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)
|
|
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)
|
|
30949
|
-
outline-
|
|
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
|
-
|
|
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
|
-
|
|
30966
|
-
outline-
|
|
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
|
-
|
|
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
|
-
|
|
31012
|
-
|
|
31013
|
-
|
|
31014
|
-
|
|
31015
|
-
|
|
31016
|
-
|
|
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:
|
|
31029
|
-
border:
|
|
31030
|
-
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);
|
|
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:
|
|
31061
|
+
overflow: hidden;
|
|
31034
31062
|
overscroll-behavior: none;
|
|
31035
31063
|
|
|
31036
|
-
|
|
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
|
-
|
|
31050
|
-
|
|
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:
|
|
31065
|
-
border:
|
|
31066
|
-
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);
|
|
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
|
-
|
|
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(
|
|
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(
|
|
31383
|
-
moveFocusToSelect(
|
|
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:
|
|
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(
|
|
31542
|
+
moveFocusToSelect(event);
|
|
31442
31543
|
}
|
|
31443
31544
|
},
|
|
31444
|
-
|
|
31545
|
+
positionX: "left-aligned",
|
|
31546
|
+
positionY: "below-overlap",
|
|
31445
31547
|
scrollTrap: scrollTrap,
|
|
31446
31548
|
pointerTrap: pointerTrap,
|
|
31447
31549
|
focusTrap: focusTrap,
|
|
31448
|
-
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, {
|
|
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 (
|
|
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(
|
|
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,
|