@jsenv/navi 0.29.190 → 0.29.192

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.
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { installImportMetaCssBuild, windowHeightSignal, windowWidthSignal, visualViewportHeightSignal, visualViewportWidthSignal, getAppHeight, getAppWidth, coarsePointerSignal, smallTouchScreenSignal } from "./jsenv_navi_side_effects.js";
6
6
  export { disableVirtualKeyboardOverlay } from "./jsenv_navi_side_effects.js";
7
- import { elementIsFocusable, createIterableWeakSet, dispatchInternalCustomEvent, dispatchCustomEvent, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, getElementSignature, createPubSub, findEvent, createValueEffect, findFocusDelegateTarget, findFocusable, scrollIntoViewThroughScrollables, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, ELEMENT_SIZE_CHANGE, findSelfOrAncestorFixedPosition, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, applyNewPosition, measureLongestVisualLineWidth, chainEvent, keepTouchRefusable, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, markDragSource, startDragTo, createEventGroupLogger, getKeyboardEventDefaultAction, activeElementSignal, normalizeStyle, mergeOneStyle, getPositionedParent, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, scrollRoomTowards, getScrollContainer, closestOpenableAncestor, isAncestorOpen, isDisplayedDespiteClosedAncestor, observeAncestorOpenState, getAncestorOpenType, findBefore, findAfter, resolveCSSSize, hasCSSSizeUnit, releaseWheelGesture, getScrollIntoViewScopedOffsets, wheelGestureIsTakenFrom, claimWheelGesture, scrollIntoViewScoped, initFocusGroup, isTouchDrivenEvent, stringifyStyle as stringifyStyle$1, resolveOklchLightness, contrastColor, parsePositionArea, snapToPixel, trapFocusInside, trapScrollInside, onAncestorReopen, isPressDisputedByDrag, canScroll, measureWidestChildRow, performTabNavigation, dragAfterIntent, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
7
+ import { elementIsFocusable, createIterableWeakSet, dispatchInternalCustomEvent, dispatchCustomEvent, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, getElementSignature, createPubSub, findEvent, createValueEffect, findFocusDelegateTarget, findFocusable, scrollIntoViewThroughScrollables, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, ELEMENT_SIZE_CHANGE, findSelfOrAncestorFixedPosition, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, applyNewPosition, measureLongestVisualLineWidth, chainEvent, keepTouchRefusable, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, markDragSource, startDragTo, createEventGroupLogger, getKeyboardEventDefaultAction, activeElementSignal, normalizeStyle, mergeOneStyle, getPositionedParent, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, scrollRoomTowards, getScrollContainer, closestOpenableAncestor, isAncestorOpen, isDisplayedDespiteClosedAncestor, observeAncestorOpenState, getAncestorOpenType, findBefore, findAfter, resolveCSSSize, hasCSSSizeUnit, releaseWheelGesture, getScrollIntoViewScopedOffsets, wheelGestureIsTakenFrom, claimWheelGesture, scrollIntoViewScoped, initFocusGroup, isTouchDrivenEvent, stringifyStyle as stringifyStyle$1, resolveOklchLightness, contrastColor, parsePositionArea, snapToPixel, trapFocusInside, trapScrollInside, getVirtualKeyboardOverlayHeight, onAncestorReopen, isPressDisputedByDrag, canScroll, measureWidestChildRow, performTabNavigation, dragAfterIntent, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
8
8
  export { chainEvent, clickIsSuppressed, contrastColor, createDragGestureController, dragAfterIntent, findEvent, markDragSource, startDragTo } from "@jsenv/dom";
9
9
  import { signal, computed, effect, untracked, batch, useComputed, useSignal } from "@preact/signals";
10
10
  import { isValidElement, createContext, render, h, toChildArray, options, cloneElement, Fragment as Fragment$1 } from "preact";
@@ -6019,7 +6019,13 @@ const css$12 = /* css */ `
6019
6019
  To ensure ti goes above we put a z-index: 1, I hope it won't bite use in the future */
6020
6020
  z-index: 1;
6021
6021
  /* Callout styles */
6022
- display: block;
6022
+ /* No display declared here on purpose: the UA rule hiding a closed popover
6023
+ is the only thing that takes a hidden callout off screen, and any author
6024
+ display beats it (author origin wins over the UA stylesheet whatever the
6025
+ specificity). Overridden, hidePopover() leaves the box painted — out of
6026
+ the top layer, so laid out against the nearest positioned ancestor while
6027
+ its placement is written in document coordinates: drawn at the wrong
6028
+ place instead of not at all. */
6023
6029
  height: auto; /* User agent reset */
6024
6030
  margin: 0;
6025
6031
  padding: 0; /* User agent reset */
@@ -10524,17 +10530,27 @@ const swipeTypeOf = (axis, pulled) => {
10524
10530
  * two, refuse.
10525
10531
  *
10526
10532
  * interactions={{ land: (event) => {
10527
- * const { fromId, toId, syncCloneWithDropTarget } = event.detail;
10533
+ * const { fromId, toId, x, y, syncCloneWithDropTarget } = event.detail;
10528
10534
  * …
10529
10535
  * }}}
10530
10536
  *
10531
10537
  * `toId` is an element and never null: a copy over nothing is a release that meant
10532
- * nothing, and the interaction does not happen at all.
10538
+ * nothing, and the interaction does not happen at all — unless the element says
10539
+ * `data-toss-by="release-outside"` (see below), which gives that release a
10540
+ * meaning of its own.
10541
+ *
10542
+ * WHERE ON IT, in `x`, `y`, `width`, `height`: the box the copy came down in,
10543
+ * measured inside the place — its border and its scroll taken out. A place that is
10544
+ * a SURFACE — a plan, a map, a floor — has no element under the copy to name and
10545
+ * nothing to swap with: where it came down IS the answer, and `toId` says which
10546
+ * surface rather than which piece.
10533
10547
  *
10534
10548
  * `syncCloneWithDropTarget` takes an element here, which `reorder` has no use for:
10535
10549
  * a place of a board can be larger than what stands on it (a quarter of a court, a
10536
10550
  * square holding a smaller piece), and the copy has to come down where the piece
10537
- * will be rather than filling the place. Left alone, it lands on the place itself.
10551
+ * will be rather than filling the place. Left alone, it lands on the place itself —
10552
+ * so a surface either passes what the thing becomes or does not call it at all,
10553
+ * which leaves the copy where the hand put it, over the thing appearing there.
10538
10554
  *
10539
10555
  * WHICH ELEMENTS ARE PLACES: those marked `data-droppable`, and only those.
10540
10556
  * Declaring `land` says an element can be CARRIED, which on a board is a different
@@ -10543,9 +10559,30 @@ const swipeTypeOf = (axis, pulled) => {
10543
10559
  * case (dropped on a piece, the two swap). A list has no such distinction — every
10544
10560
  * row is both, which is why `reorder` needs no marker in the markup.
10545
10561
  *
10546
- * The set of places is looked for inside the carried element's PARENT, so a place
10547
- * and a piece are siblings: a piece nested inside its place would see only that
10548
- * one, and have nowhere else to go.
10562
+ * WHERE THE PLACES ARE LOOKED FOR: inside the carried element's PARENT, so a place
10563
+ * and a piece are siblings — and `data-drop-container` on an ancestor says
10564
+ * otherwise. Two arrangements need it, and both are the same one: what is carried
10565
+ * does not stand among the places. A palette is a strip BESIDE the surface it
10566
+ * fills, a marker already placed is drawn INSIDE the surface it can be put back
10567
+ * on, and in each case the search must cover what holds both. It holds the places
10568
+ * rather than being one — a surface carrying it would never be found from inside
10569
+ * itself. It is also what lets the copy travel there: named, the area it may cross
10570
+ * is the page rather than the source's own scroll area.
10571
+ *
10572
+ * <div data-drop-container>
10573
+ * <aside>{shapes.map((shape) => <Shape interactions={{ land: add }} />)}</aside>
10574
+ * <Plan id="plan" data-droppable>…</Plan>
10575
+ * </div>
10576
+ *
10577
+ * HOW A TOSS IS MADE: `data-toss-by`, beside `toss`. A THROW (`"throw"`, the
10578
+ * default) is far AND fast — the flick that gets rid of something, a list's
10579
+ * gesture, and it is judged before any landing. A RELEASE OUTSIDE
10580
+ * (`"release-outside"`) has no place under it — dragging a marker off a plan and
10581
+ * letting go, deliberate and never a flick, a surface's gesture. Each is named on
10582
+ * its own because each is wrong where the other is right: on a plan a fast drag
10583
+ * that ends ON it has not asked for the thing to go, and on a list a row let go of
10584
+ * beside it is a row put back. Both at once is
10585
+ * `data-toss-by="throw release-outside"`.
10549
10586
  *
10550
10587
  * Nothing of the gesture is decided here. `startDragTo` owns all of it — the
10551
10588
  * copy carried above the page while the original keeps its place in the layout, the
@@ -10635,6 +10672,8 @@ const REORDERABLE_ATTRIBUTE = "data-reorderable";
10635
10672
  // The same for `land`, except the markup is what writes it: a place of a board is
10636
10673
  // not the same thing as a piece of it (see the top of this file).
10637
10674
  const DROPPABLE_ATTRIBUTE = "data-droppable";
10675
+ // What holds the places, when the carried element does not stand among them.
10676
+ const DROP_CONTAINER_ATTRIBUTE = "data-drop-container";
10638
10677
  // Which axes the drag walks: "x", "y" or "xy". Its default is not the same for
10639
10678
  // every outcome — a list runs one way, and something being put somewhere goes
10640
10679
  // wherever it is put.
@@ -10644,6 +10683,11 @@ const SLOP_ATTRIBUTE = "data-drag-slop";
10644
10683
  const THRESHOLD_ATTRIBUTE = "data-drag-threshold";
10645
10684
  const TOSS_DISTANCE_ATTRIBUTE = "data-toss-distance";
10646
10685
  const TOSS_SPEED_ATTRIBUTE = "data-toss-speed";
10686
+ // How a toss is made here: "throw" (far and fast), "release-outside" (let go of
10687
+ // away from every place), or both.
10688
+ const TOSS_BY_ATTRIBUTE = "data-toss-by";
10689
+ const TOSS_BY_DEFAULT = "throw";
10690
+ const TOSS_WAYS = ["throw", "release-outside"];
10647
10691
 
10648
10692
  defineInteractionDetector({
10649
10693
  name: "drag",
@@ -10691,6 +10735,33 @@ defineInteractionDetector({
10691
10735
  // the hand takes it: a board has places all around, a thing put somewhere has
10692
10736
  // two axes to be put along, and a throw goes where it was thrown.
10693
10737
  (canReorder && !canLand && !canToss ? "y" : "xy");
10738
+ // Where the places are, and what a release away from all of them means —
10739
+ // both read at setup for the same reason as the axes: they are what the
10740
+ // gesture is about, and it is what holds the two sides of it that says them.
10741
+ const dropContainer = element.closest(`[${DROP_CONTAINER_ATTRIBUTE}]`);
10742
+ const tossByHolder = element.closest(`[${TOSS_BY_ATTRIBUTE}]`);
10743
+ const tossBy = (
10744
+ tossByHolder?.getAttribute(TOSS_BY_ATTRIBUTE) || TOSS_BY_DEFAULT
10745
+ )
10746
+ .trim()
10747
+ .split(/\s+/);
10748
+ {
10749
+ for (const way of tossBy) {
10750
+ if (!TOSS_WAYS.includes(way)) {
10751
+ console.warn(
10752
+ `interactions: "${way}" is not a way a toss is made. ${TOSS_BY_ATTRIBUTE} takes "${TOSS_WAYS.join('", "')}", or both.`,
10753
+ );
10754
+ }
10755
+ }
10756
+ if (
10757
+ tossBy.includes("release-outside") &&
10758
+ (!canToss || (!canReorder && !canLand))
10759
+ ) {
10760
+ console.warn(
10761
+ `interactions: ${TOSS_BY_ATTRIBUTE}="release-outside" makes a release away from every place mean the thing is gotten rid of, so it needs both "${TOSS}" and places to be away from. Declare "${TOSS}" beside "${REORDER}" or "${LAND}".`,
10762
+ );
10763
+ }
10764
+ }
10694
10765
 
10695
10766
  if (canReorder) {
10696
10767
  element.setAttribute(REORDERABLE_ATTRIBUTE, "");
@@ -10717,23 +10788,29 @@ defineInteractionDetector({
10717
10788
  : canReorder
10718
10789
  ? `[${REORDERABLE_ATTRIBUTE}]`
10719
10790
  : undefined,
10791
+ containerElement: dropContainer || undefined,
10720
10792
  getItemId: (itemElement) => itemElement.id,
10721
10793
  direction: { x: axes.includes("x"), y: axes.includes("y") },
10722
10794
  // Where it may go, said in the DOM. A thing that is put somewhere stays
10723
10795
  // inside what one can SEE of its container ("scrollport", not "scroll":
10724
10796
  // the scrollable area can be far larger than the box, and "inside the box"
10725
- // is what a hand expects). `data-drag-free` lifts that. Left alone for a
10726
- // throw, which frees the area on its own — it has to be able to leave.
10727
- areaConstraint: element.closest(`[data-drag-free]`)
10728
- ? "none"
10729
- : canMove
10730
- ? "scrollport"
10731
- : undefined,
10797
+ // is what a hand expects). `data-drag-free` lifts that, and so does a
10798
+ // named container of places: they are somewhere else by construction, and
10799
+ // a copy kept in its own scroll area could never reach them. Left alone
10800
+ // for a throw, which frees the area on its own — it has to be able to
10801
+ // leave.
10802
+ areaConstraint:
10803
+ dropContainer || element.closest(`[data-drag-free]`)
10804
+ ? "none"
10805
+ : canMove
10806
+ ? "scrollport"
10807
+ : undefined,
10732
10808
  threshold: readConfig(THRESHOLD_ATTRIBUTE, undefined),
10733
10809
  longPressDelay: readConfig(DELAY_ATTRIBUTE, undefined),
10734
10810
  longPressSlop: readConfig(SLOP_ATTRIBUTE, undefined),
10735
10811
  tossDistance: readConfig(TOSS_DISTANCE_ATTRIBUTE, undefined),
10736
10812
  tossSpeed: readConfig(TOSS_SPEED_ATTRIBUTE, undefined),
10813
+ tossBy,
10737
10814
  // The one moment the gesture has that is not a release. Said here rather
10738
10815
  // than from the press that led to it, because the press is only one of the
10739
10816
  // two ways in: a finger holds still, a mouse travels a few pixels, and it
@@ -10756,12 +10833,7 @@ defineInteractionDetector({
10756
10833
  toId,
10757
10834
  syncCloneWithDropTarget,
10758
10835
  }),
10759
- onLand: (fromId, toId, syncCloneWithDropTarget) =>
10760
- trigger(LAND, pointerDownEvent, {
10761
- fromId,
10762
- toId,
10763
- syncCloneWithDropTarget,
10764
- }),
10836
+ onLand: (detail) => trigger(LAND, pointerDownEvent, detail),
10765
10837
  onToss: ({ gestureInfo }) =>
10766
10838
  trigger(TOSS, pointerDownEvent, {
10767
10839
  id: element.id,
@@ -19881,6 +19953,7 @@ import.meta.css = /* css */[`[data-scrollable] > .navi_loading_outline_wrapper,
19881
19953
 
19882
19954
  [data-scrollable] {
19883
19955
  overflow: var(--x-scrollable-overflow, auto);
19956
+ scroll-padding: var(--navi-scroll-padding, var(--navi-s));
19884
19957
  --box-header-z-index: var(--navi-z-index-sticky);
19885
19958
  --box-footer-z-index: var(--navi-z-index-sticky);
19886
19959
  isolation: isolate;
@@ -19925,8 +19998,9 @@ import.meta.css = /* css */[`[data-scrollable] > .navi_loading_outline_wrapper,
19925
19998
  border-bottom-left-radius: inherit;
19926
19999
  outline-width: var(--navi-focus-outline-width);
19927
20000
  outline-offset: calc(-1 * var(--navi-focus-outline-width));
19928
- flex: 0 auto;
19929
20001
  min-height: 0;
20002
+ scroll-padding: var(--navi-scroll-padding, var(--navi-s));
20003
+ flex: 0 auto;
19930
20004
  overflow: auto;
19931
20005
 
19932
20006
  &:focus-visible {
@@ -44890,6 +44964,7 @@ const mayHaveHiddenFocus = (event) => {
44890
44964
  );
44891
44965
  };
44892
44966
 
44967
+ const scrollportHeightMap = new WeakMap();
44893
44968
  /**
44894
44969
  * Scrolls whatever holds focus inside `popupEl` back into view, if the popup
44895
44970
  * getting shorter has pushed it out.
@@ -44904,14 +44979,27 @@ const mayHaveHiddenFocus = (event) => {
44904
44979
  * past its bottom edge — visually, swallowed by the footer. The browser does
44905
44980
  * not redo a scroll-into-view it already answered, so this does.
44906
44981
  *
44982
+ * Only what the shrink itself hid, though: with the keyboard up the user reads
44983
+ * the rest of the popup by scrolling the field away — to reach the submit under
44984
+ * it, typically — and the room keeps changing while they do (a keyboard settling
44985
+ * in two steps, a suggestion strip, a browser bar). Answering each of those by
44986
+ * scrolling the field back takes the popup away from wherever they had just
44987
+ * scrolled it, over and over: what they were reading cannot be reached at all
44988
+ * without blurring the field first, and the popup reads as unscrollable. So the
44989
+ * field is brought back only when it was in view before the room shrank, which
44990
+ * one remembered number answers: a resize moves neither scrollTop nor the
44991
+ * element's offset inside the scrolled content, so measuring against the height
44992
+ * the scrollport HAD is measuring the state before the change.
44993
+ *
44907
44994
  * Scoped to the field's own scroll container (never the page): a popup traps
44908
44995
  * scrolling precisely so the document underneath cannot move, and a plain
44909
44996
  * scrollIntoView walks past a container whose scrollbar isn't visible — see
44910
44997
  * scrollIntoViewScoped's own doc.
44911
44998
  *
44912
- * "nearest": the smallest scroll that makes it visible, and none at all when
44913
- * it already is — so this is free to call on every resize, and never fights
44914
- * where the user had scrolled to.
44999
+ * "nearest": the smallest scroll that makes it visible, and none at all when it
45000
+ * already is. Where it lands is the container's own business — a navi scroller
45001
+ * keeps a band free at its edges so a field never comes back glued to one (see
45002
+ * scroll-padding in box.jsx).
44915
45003
  */
44916
45004
  const keepFocusedElementVisible = (popupEl) => {
44917
45005
  const { activeElement } = document;
@@ -44921,7 +45009,49 @@ const keepFocusedElementVisible = (popupEl) => {
44921
45009
  if (!popupEl.contains(activeElement)) {
44922
45010
  return;
44923
45011
  }
44924
- scrollIntoViewScoped(activeElement, { block: "nearest" });
45012
+ const scrollContainer = getScrollContainer(activeElement);
45013
+ if (!scrollContainer || !popupEl.contains(scrollContainer)) {
45014
+ // What scrolls the field is outside the popup, which means the page: a
45015
+ // popup holds it still on purpose (trapScrollInside), so there is nothing
45016
+ // here to scroll back.
45017
+ return;
45018
+ }
45019
+ const scrollportHeight = scrollContainer.clientHeight;
45020
+ const scrollportHeightBefore = scrollportHeightMap.get(scrollContainer);
45021
+ scrollportHeightMap.set(scrollContainer, scrollportHeight);
45022
+ if (scrollportHeightBefore !== undefined) {
45023
+ if (scrollportHeight >= scrollportHeightBefore) {
45024
+ // Nothing was taken away, so nothing was hidden by this.
45025
+ return;
45026
+ }
45027
+ if (
45028
+ !isVisibleInScrollport(
45029
+ activeElement,
45030
+ scrollContainer,
45031
+ scrollportHeightBefore,
45032
+ )
45033
+ ) {
45034
+ return;
45035
+ }
45036
+ }
45037
+ scrollIntoViewScoped(activeElement, {
45038
+ container: scrollContainer,
45039
+ block: "nearest",
45040
+ });
45041
+ };
45042
+
45043
+ // Whether any part of `el` was showing in `container` back when its scrollport
45044
+ // was `scrollportHeight` tall. Both boxes are read now: the container may have
45045
+ // moved as well as shrunk (a centered dialog re-centers itself), and the
45046
+ // difference between the two tops is what that move leaves alone.
45047
+ const isVisibleInScrollport = (el, container, scrollportHeight) => {
45048
+ const elRect = el.getBoundingClientRect();
45049
+ const containerRect = container.getBoundingClientRect();
45050
+ const elTop = elRect.top - containerRect.top + container.scrollTop;
45051
+ const elBottom = elTop + elRect.height;
45052
+ const scrollportTop = container.scrollTop;
45053
+ const scrollportBottom = scrollportTop + scrollportHeight;
45054
+ return elBottom > scrollportTop && elTop < scrollportBottom;
44925
45055
  };
44926
45056
 
44927
45057
  /**
@@ -44968,6 +45098,32 @@ const whenTransitionSettles = (el, onSettled) => {
44968
45098
  };
44969
45099
  };
44970
45100
 
45101
+ /**
45102
+ * Drops the document's text selection when it lives inside `el`, leaving a
45103
+ * selection made elsewhere on the page alone.
45104
+ *
45105
+ * A popup being closed takes its content with it, and a selection is a claim
45106
+ * on content the user can still act on: kept, it would outlive the surface it
45107
+ * was made on — painted on the box for the length of its exit transition, with
45108
+ * the handles and the copy toolbar a phone draws from the live selection
45109
+ * hanging over something that is going away — and reappear with the box on
45110
+ * the next opening. Dropping the selection is the only way to remove that
45111
+ * chrome: a `user-select: none` on the closing box hides the highlight in some
45112
+ * browsers only, and the handles are the browser's own, drawn from the
45113
+ * selection object rather than from any style.
45114
+ */
45115
+ const clearTextSelectionInside = (el) => {
45116
+ const selection = window.getSelection();
45117
+ if (!selection || selection.rangeCount === 0) {
45118
+ return;
45119
+ }
45120
+ const range = selection.getRangeAt(0);
45121
+ if (!el.contains(range.commonAncestorContainer)) {
45122
+ return;
45123
+ }
45124
+ selection.removeAllRanges();
45125
+ };
45126
+
44971
45127
  /**
44972
45128
  * Disables pointer-events on `el` until its current CSS transition settles —
44973
45129
  * avoids the cursor changing/something becoming clickable while the popup is
@@ -56696,6 +56852,15 @@ const css$E = /* css */`
56696
56852
  scroll (a short body, an axis with nowhere to go) must not travel to
56697
56853
  whatever is behind. */
56698
56854
  overscroll-behavior: none;
56855
+ /* What the backdrop paints, resolved on the dialog rather than on the
56856
+ pseudo-element that paints it: ::backdrop takes no inline style and
56857
+ carries no attribute of its own, so the backdropColor/backdropFilter
56858
+ props land here — inline, beating every rule below — and the
56859
+ pseudo-element inherits whichever won. A colour and a filter travel
56860
+ together everywhere a backdrop is painted: see navi_css_vars.js for
56861
+ why a blur is not tied to what an outside click does. */
56862
+ --backdrop-background: var(--navi-backdrop-close-background);
56863
+ --backdrop-filter: var(--navi-backdrop-close-backdrop-filter);
56699
56864
 
56700
56865
  /* Docking answers a different question than --dialog-max-width: a sheet
56701
56866
  spans its container's full width, flush against the two side edges —
@@ -56746,6 +56911,7 @@ const css$E = /* css */`
56746
56911
  &[data-flush-bottom][data-flush-left] {
56747
56912
  border-bottom-left-radius: 0;
56748
56913
  }
56914
+
56749
56915
  /* The placement is a translate, so the translate property is spoken for
56750
56916
  here (see applyNewPosition in visible_rect.js, which owns it and animates
56751
56917
  it itself through the Web Animations API rather than through this file's
@@ -56753,26 +56919,26 @@ const css$E = /* css */`
56753
56919
  to filter). An entrance animation moves the dialog through scale and
56754
56920
  transform instead, which compose under it: see popup_css.js. */
56755
56921
 
56756
- &::backdrop {
56757
- background: var(--navi-backdrop-close-background);
56922
+ &[data-pointer-interaction-outside="capture"] {
56923
+ --backdrop-background: var(--navi-backdrop-capture-background);
56924
+ --backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
56758
56925
  }
56759
- &[data-pointer-interaction-outside="capture"]::backdrop {
56760
- background: var(--navi-backdrop-capture-background);
56761
- backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
56926
+ /* backdropVariant, after the rules it overrides: same specificity, so
56927
+ order is what decides. showModal() still makes the page inert either
56928
+ way — only the paint goes away. */
56929
+ &[data-backdrop-variant="discrete"] {
56930
+ --backdrop-background: var(--navi-backdrop-discrete-background);
56931
+ --backdrop-filter: var(--navi-backdrop-discrete-backdrop-filter);
56762
56932
  }
56763
-
56764
- /* backdropVariant, keyed off the originating element (a
56765
- pseudo-element carries no attributes of its own — same reasoning as
56766
- the capture rule just above). After the rules it overrides: same
56767
- specificity, so order is what decides. showModal() still makes the
56768
- page inert either way — only the paint goes away. */
56769
- &[data-backdrop-variant="discrete"]::backdrop {
56770
- background: var(--navi-backdrop-discrete-background);
56771
- backdrop-filter: none;
56933
+ /* The one backdrop with nothing to blur through: "invisible" paints
56934
+ nothing at all, and a filter would still be seen. */
56935
+ &[data-backdrop-variant="invisible"] {
56936
+ --backdrop-background: transparent;
56937
+ --backdrop-filter: none;
56772
56938
  }
56773
- &[data-backdrop-variant="invisible"]::backdrop {
56774
- background: transparent;
56775
- backdrop-filter: none;
56939
+ &::backdrop {
56940
+ background: var(--backdrop-background);
56941
+ backdrop-filter: var(--backdrop-filter);
56776
56942
  }
56777
56943
 
56778
56944
  /* Nested under &[navi-animation] (not the other way around) so every
@@ -56882,6 +57048,17 @@ const css$E = /* css */`
56882
57048
  in openEffect) gets pointer-events: none mid-transition. */
56883
57049
  pointer-events: auto;
56884
57050
 
57051
+ /* Painted through the same two variables as the via-attribute renderer's
57052
+ ::backdrop (see them for what each rule is for) — here they resolve on
57053
+ the element that paints, which is also the element the
57054
+ backdropColor/backdropFilter props are set on. Declared unconditionally
57055
+ first so a variable inherited from a dialog this popup was opened from
57056
+ can never reach the paint. */
57057
+ --backdrop-background: transparent;
57058
+ --backdrop-filter: none;
57059
+ background: var(--backdrop-background);
57060
+ backdrop-filter: var(--backdrop-filter);
57061
+
56885
57062
  /* A plain div, unlike dialogEl itself (a real <dialog>, natively hidden
56886
57063
  by default until .show()/.showModal() adds [open]) — needs its own
56887
57064
  starting-hidden mechanism. [navi-hidden] is set from useDialogProps'
@@ -56898,23 +57075,20 @@ const css$E = /* css */`
56898
57075
  /* Makes pointerInteractionOutsideEffect have a visible impact on backdrop */
56899
57076
  &[data-pointer-interaction-outside="close"],
56900
57077
  &[data-pointer-interaction-outside="cancel"] {
56901
- background: var(--navi-backdrop-close-background);
57078
+ --backdrop-background: var(--navi-backdrop-close-background);
57079
+ --backdrop-filter: var(--navi-backdrop-close-backdrop-filter);
56902
57080
  }
56903
57081
  &[data-pointer-interaction-outside="capture"] {
56904
- background: var(--navi-backdrop-capture-background);
56905
- backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
57082
+ --backdrop-background: var(--navi-backdrop-capture-background);
57083
+ --backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
56906
57084
  }
56907
-
56908
- /* Same override as the via-attribute renderer's own ::backdrop rules
56909
- above, on the real element this renderer uses instead — see them for
56910
- the specificity/ordering reasoning. */
56911
57085
  &[data-backdrop-variant="discrete"] {
56912
- background: var(--navi-backdrop-discrete-background);
56913
- backdrop-filter: none;
57086
+ --backdrop-background: var(--navi-backdrop-discrete-background);
57087
+ --backdrop-filter: var(--navi-backdrop-discrete-backdrop-filter);
56914
57088
  }
56915
57089
  &[data-backdrop-variant="invisible"] {
56916
- background: transparent;
56917
- backdrop-filter: none;
57090
+ --backdrop-background: transparent;
57091
+ --backdrop-filter: none;
56918
57092
  }
56919
57093
 
56920
57094
  /* overlay is a no-op here (this backdrop is a plain div, never a
@@ -57041,6 +57215,17 @@ const css$E = /* css */`
57041
57215
  * barely-there dim. `"invisible"`: fully transparent. The dialog stays modal
57042
57216
  * either way — this only changes how much it insists visually, never what
57043
57217
  * an outside click does or whether the page behind stays reachable.
57218
+ * @param {string} [props.backdropColor] - The wash painted over what is
57219
+ * behind, for this popup alone: any CSS color (`"rgb(6 10 20 / 88%)"`).
57220
+ * Wins over `backdropVariant` and over the theme tokens
57221
+ * (`--navi-backdrop-*-background`), which is where the same choice goes
57222
+ * when it is the whole app's.
57223
+ * @param {string} [props.backdropFilter] - What that same wash does to the
57224
+ * picture underneath: `"blur(4px)"` to keep the page behind recognisable
57225
+ * while it stops being readable. A `backdrop-filter` value, so
57226
+ * `saturate()`/`grayscale()` work too. How far what is behind withdraws is
57227
+ * a question of paint, not of what an outside click does — a backdrop that
57228
+ * closes can blur.
57044
57229
  * @param {boolean} [props.scrollCapture] - Traps scroll gestures inside the
57045
57230
  * dialog so the page/container behind it can't scroll while it's open.
57046
57231
  * A `layer="local"` dialog always locks its own positioned ancestor's
@@ -57377,6 +57562,13 @@ const useDialogProps = props => {
57377
57562
  // always modal, so "none" here never makes the page behind reachable:
57378
57563
  // it only stops the dim from being drawn.
57379
57564
  backdropVariant = "auto",
57565
+ // The paint itself, when the tokens behind backdropVariant are not what
57566
+ // this one dialog wants. Named/forwarded rather than left in ...rest:
57567
+ // rest lands on the dialog element, and these belong to the backdrop —
57568
+ // which is the pseudo-element of one renderer and a sibling of the other,
57569
+ // so both objects below get them (see this file's CSS).
57570
+ backdropColor,
57571
+ backdropFilter,
57380
57572
  scrollCapture: scrollCaptureProp,
57381
57573
  // "auto" (default) → the dialog follows its content. "frozen" → measured
57382
57574
  // once, held at that size while open. See this prop's own JSDoc above.
@@ -57811,6 +58003,33 @@ const useDialogProps = props => {
57811
58003
  // recheck its own position whenever this dialog itself moves is
57812
58004
  // handled generically by applyNewPosition itself (dispatches
57813
58005
  // navi_position_change on every call) — nothing to do here.
58006
+ logPlacement(triggerEvent, position);
58007
+ };
58008
+ // The whole picture in one line: where the dialog ended up, and what it
58009
+ // believed about the room when it decided. Both are needed together — a box
58010
+ // that looks wrong on screen while these numbers are right means something
58011
+ // covers the screen that no API describes (a phone's autofill/suggestion
58012
+ // strip), and the absence of a line after the keyboard arrives means the
58013
+ // placement was never asked to run again.
58014
+ const logPlacement = (triggerEvent, position) => {
58015
+ // The decided target, never the current rect: the placement animates, so
58016
+ // a box read right after applying one is somewhere between the two and
58017
+ // reads like a decision nobody took.
58018
+ const {
58019
+ visualViewport
58020
+ } = window;
58021
+ // Reads nothing that brings the layout up to date — no getComputedStyle,
58022
+ // no window.innerWidth/innerHeight. That is the very thing this line is
58023
+ // here to observe (see getVisibleViewportRect in @jsenv/dom): a log that
58024
+ // forced it would hand the NEXT placement a fresh viewport and hide the
58025
+ // bug it was printed to show. Everything below is either already computed
58026
+ // (the pick's own numbers, "room" being the room it had) or free to read.
58027
+ const message = `placed on "${triggerEvent ? triggerEvent.type : "open"}": ${Math.round(position.width)}x${Math.round(position.height)} at ${Math.round(position.top)}->${Math.round(position.top + position.height)} | room ${Math.round(position.containerHeightAvailable)} | viewport ${Math.round(visualViewport.width)}x${Math.round(visualViewport.height)} +${Math.round(visualViewport.offsetLeft)},${Math.round(visualViewport.offsetTop)} | keyboard ${getVirtualKeyboardOverlayHeight()}`;
58028
+ if (triggerEvent) {
58029
+ debugPopup(triggerEvent, message);
58030
+ } else {
58031
+ debugPopup(message);
58032
+ }
57814
58033
  };
57815
58034
  // Cleared here rather than on close, where the box is deliberately left
57816
58035
  // frozen at the size it was closing at (see the closing function's own
@@ -57958,6 +58177,7 @@ const useDialogProps = props => {
57958
58177
  }
57959
58178
  return closeEvent => {
57960
58179
  debugPopup(`"${closeEvent.type}" on ${getElementSignature(closeEvent.target)} -> closeDialog`);
58180
+ clearTextSelectionInside(dialogEl);
57961
58181
  dialogEl.setAttribute("aria-expanded", "false");
57962
58182
  if (!isModal) {
57963
58183
  openLocalDialogCount = Math.max(0, openLocalDialogCount - 1);
@@ -58045,7 +58265,9 @@ const useDialogProps = props => {
58045
58265
  "styleCSSVars": DIALOG_STYLE_CSS_VARS,
58046
58266
  "animationDuration": rest.animationDuration,
58047
58267
  "data-pointer-interaction-outside": pointerInteractionOutsideEffect,
58048
- "data-backdrop-variant": backdropVariant
58268
+ "data-backdrop-variant": backdropVariant,
58269
+ backdropColor,
58270
+ backdropFilter
58049
58271
  });
58050
58272
  Object.assign(contentProps, {
58051
58273
  tabIndex,
@@ -58079,6 +58301,11 @@ const useDialogProps = props => {
58079
58301
  // as the prop just above (and harmless for the custom renderer, whose
58080
58302
  // real backdrop element gets it via backdropProps).
58081
58303
  "data-backdrop-variant": backdropVariant,
58304
+ // Read by the native ::backdrop, which inherits them from here (see this
58305
+ // file's CSS) — the custom renderer's own backdrop element gets them via
58306
+ // backdropProps above.
58307
+ backdropColor,
58308
+ backdropFilter,
58082
58309
  "styleCSSVars": DIALOG_STYLE_CSS_VARS,
58083
58310
  ...rest,
58084
58311
  ...autoFocusProps,
@@ -58195,6 +58422,8 @@ const DIALOG_PSEUDO_CLASSES = [":hover", ":active", ":focus", ":focus-visible",
58195
58422
  // an inline border-radius would outrank them.
58196
58423
  const DIALOG_STYLE_CSS_VARS = {
58197
58424
  animationDuration: "--popup-animation-duration",
58425
+ backdropColor: "--backdrop-background",
58426
+ backdropFilter: "--backdrop-filter",
58198
58427
  borderRadius: "--dialog-border-radius",
58199
58428
  minWidth: "--dialog-min-width",
58200
58429
  maxWidth: "--dialog-max-width",
@@ -58428,8 +58657,18 @@ const css$D = /* css */`
58428
58657
  z-index: calc(var(--navi-z-index-popup) + var(--popover-stack-order, 0));
58429
58658
  margin: 0;
58430
58659
  padding: 0;
58431
- background: transparent;
58660
+ /* What this backdrop paints, in two variables the rules below write as
58661
+ defaults — so the backdropColor/backdropFilter props, inline on this
58662
+ very element, beat all of them. Declared unconditionally first so a
58663
+ variable inherited from a dialog this popover was opened from can never
58664
+ reach the paint. A colour and a filter travel together everywhere a
58665
+ backdrop is painted: see navi_css_vars.js for why a blur is not tied to
58666
+ what an outside click does. */
58667
+ --backdrop-background: transparent;
58668
+ --backdrop-filter: none;
58669
+ background: var(--backdrop-background);
58432
58670
  border: none;
58671
+ backdrop-filter: var(--backdrop-filter);
58433
58672
  /* Always clickable while actually rendered (display: none/hidePopover()
58434
58673
  while genuinely closed already makes it non-interactive on its own)
58435
58674
  — an outside click should close the popover even while it's still
@@ -58460,11 +58699,12 @@ const css$D = /* css */`
58460
58699
  /* Makes pointerInteractionOutsideEffect have a visible impact on backdrop */
58461
58700
  &[data-pointer-interaction-outside="close"],
58462
58701
  &[data-pointer-interaction-outside="cancel"] {
58463
- background: var(--navi-backdrop-close-background);
58702
+ --backdrop-background: var(--navi-backdrop-close-background);
58703
+ --backdrop-filter: var(--navi-backdrop-close-backdrop-filter);
58464
58704
  }
58465
58705
  &[data-pointer-interaction-outside="capture"] {
58466
- background: var(--navi-backdrop-capture-background);
58467
- backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
58706
+ --backdrop-background: var(--navi-backdrop-capture-background);
58707
+ --backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
58468
58708
  }
58469
58709
 
58470
58710
  /* backdropVariant overrides whatever the effect above picked — same
@@ -58473,12 +58713,14 @@ const css$D = /* css */`
58473
58713
  and still pointer-events: auto, so an outside click keeps doing
58474
58714
  exactly what pointerInteractionOutsideEffect says. */
58475
58715
  &[data-backdrop-variant="discrete"] {
58476
- background: var(--navi-backdrop-discrete-background);
58477
- backdrop-filter: none;
58716
+ --backdrop-background: var(--navi-backdrop-discrete-background);
58717
+ --backdrop-filter: var(--navi-backdrop-discrete-backdrop-filter);
58478
58718
  }
58719
+ /* The one backdrop with nothing to blur through: "invisible" paints
58720
+ nothing at all, and a filter would still be seen. */
58479
58721
  &[data-backdrop-variant="invisible"] {
58480
- background: transparent;
58481
- backdrop-filter: none;
58722
+ --backdrop-background: transparent;
58723
+ --backdrop-filter: none;
58482
58724
  }
58483
58725
 
58484
58726
  /* navi-animation mirrors the content popover's own resolved value (set
@@ -58558,6 +58800,17 @@ const css$D = /* css */`
58558
58800
  * changes how much the popover insists on being the thing you deal with.
58559
58801
  * Ignored when `pointerInteractionOutsideEffect="none"` (there is no
58560
58802
  * backdrop at all then, and outside clicks pass through).
58803
+ * @param {string} [props.backdropColor] - The wash painted over what is
58804
+ * behind, for this popup alone: any CSS color (`"rgb(6 10 20 / 88%)"`).
58805
+ * Wins over `backdropVariant` and over the theme tokens
58806
+ * (`--navi-backdrop-*-background`), which is where the same choice goes
58807
+ * when it is the whole app's.
58808
+ * @param {string} [props.backdropFilter] - What that same wash does to the
58809
+ * picture underneath: `"blur(4px)"` to keep the page behind recognisable
58810
+ * while it stops being readable. A `backdrop-filter` value, so
58811
+ * `saturate()`/`grayscale()` work too. How far what is behind withdraws is
58812
+ * a question of paint, not of what an outside click does — a backdrop that
58813
+ * closes can blur.
58561
58814
  * @param {boolean} [props.scrollCapture] - Traps scroll gestures inside the
58562
58815
  * popover so the page/container behind it can't scroll while it's open.
58563
58816
  * @param {boolean} [props.focusCapture] - Traps Tab navigation inside the
@@ -58869,6 +59122,12 @@ const usePopoverProps = props => {
58869
59122
  // the paint the effect implies; "discrete"/"none" tone it down or
58870
59123
  // remove it entirely without giving up the outside click.
58871
59124
  backdropVariant = "auto",
59125
+ // The paint itself, when the tokens behind backdropVariant are not what
59126
+ // this one popover wants. Named/forwarded rather than left in ...rest:
59127
+ // rest lands on the popover element, and these belong to its backdrop,
59128
+ // which is a sibling element (see this file's top comment).
59129
+ backdropColor,
59130
+ backdropFilter,
58872
59131
  scrollCapture,
58873
59132
  focusCapture,
58874
59133
  // "auto" (default) → the popover follows its content. "frozen" → measured
@@ -59466,6 +59725,7 @@ const usePopoverProps = props => {
59466
59725
  // reason: only ever built here.
59467
59726
  return closeEvent => {
59468
59727
  debugPopup(closeEvent, `closePopover()`);
59728
+ clearTextSelectionInside(popoverEl);
59469
59729
  popoverEl.setAttribute("aria-expanded", "false");
59470
59730
  // Set regardless of isTopLayer — see the open side's own identical
59471
59731
  // comment (openEffect above) for why hidePopover() alone isn't
@@ -59581,6 +59841,8 @@ const usePopoverProps = props => {
59581
59841
  "animationDuration": rest.animationDuration,
59582
59842
  "data-pointer-interaction-outside": pointerInteractionOutsideEffect,
59583
59843
  "data-backdrop-variant": backdropVariant,
59844
+ backdropColor,
59845
+ backdropFilter,
59584
59846
  "onMouseDown": mouseDownEvent => {
59585
59847
  if (mouseDownEvent.button !== 0) {
59586
59848
  return;
@@ -59685,6 +59947,8 @@ const POPOVER_PSEUDO_CLASSES = [":hover", ":active", ":focus", ":focus-visible",
59685
59947
  // handling).
59686
59948
  const POPUP_STYLE_CSS_VARS = {
59687
59949
  animationDuration: "--popup-animation-duration",
59950
+ backdropColor: "--backdrop-background",
59951
+ backdropFilter: "--backdrop-filter",
59688
59952
  minWidth: "--popover-min-width",
59689
59953
  maxWidth: "--popover-max-width",
59690
59954
  minHeight: "--popover-min-height",
@@ -59803,6 +60067,10 @@ const css$C = /* css */`@layer navi {
59803
60067
  * how visible the backdrop is, independently of what an outside click
59804
60068
  * does. Unlike `pointerInteractionOutsideEffect` above, this one needs no
59805
60069
  * default here — `"auto"` already means the same thing on both sides.
60070
+ * @param {string} [props.backdropColor] - Forwarded as-is (both understand it
60071
+ * identically): the wash the backdrop paints over what is behind.
60072
+ * @param {string} [props.backdropFilter] - Forwarded as-is: what that wash
60073
+ * does to the picture underneath, `"blur(4px)"` and the like.
59806
60074
  * @param {boolean|"auto"|"fading"|"scaling"|"sliding"|"expanding"|`slide-from-${string}`|`expand-${string}`} [props.animation]
59807
60075
  * - Forwarded as-is.
59808
60076
  * @param {string} [props.animationDuration] - Forwarded as-is.
@@ -60671,6 +60939,8 @@ const PickerContentInsidePopup = props => {
60671
60939
  // Named/forwarded rather than left in ...rest: rest goes to the picker
60672
60940
  // element itself, not the popup, and this belongs to the popup.
60673
60941
  backdropVariant,
60942
+ backdropColor,
60943
+ backdropFilter,
60674
60944
  dialogExpand,
60675
60945
  dialogExpandX,
60676
60946
  dialogExpandY,
@@ -60746,6 +61016,8 @@ const PickerContentInsidePopup = props => {
60746
61016
  scrollCapture: scrollCapture,
60747
61017
  pointerInteractionOutsideEffect: pointerLock ? "capture" : pointerInteractionOutsideEffect,
60748
61018
  backdropVariant: backdropVariant,
61019
+ backdropColor: backdropColor,
61020
+ backdropFilter: backdropFilter,
60749
61021
  focusCapture: isPopover ? focusCapture : undefined,
60750
61022
  expand: isPopover ? undefined : dialogExpand,
60751
61023
  expandX: isPopover ? undefined : dialogExpandX,
@@ -69665,6 +69937,8 @@ const PickerFirstResolver = props => {
69665
69937
  * escapeEffect?: "cancel" | "close",
69666
69938
  * pointerInteractionOutsideEffect?: "close" | "cancel" | "capture",
69667
69939
  * backdropVariant?: "auto" | "discrete" | "invisible",
69940
+ * backdropColor?: string,
69941
+ * backdropFilter?: string,
69668
69942
  * ref?: import("ignore:preact").RefObject<HTMLElement>,
69669
69943
  * [key: string]: any,
69670
69944
  * }>}
@@ -69913,6 +70187,11 @@ const PickerFirstResolver = props => {
69913
70187
  * is the paint `pointerInteractionOutsideEffect` implies, `"discrete"` a
69914
70188
  * barely-there dim, `"invisible"` fully transparent. For a picker that closes on
69915
70189
  * an outside click without wanting to dim the page for it.
70190
+ * @param {string} [backdropColor] The wash the popup paints over what is
70191
+ * behind, for this picker alone. See Dialog's own doc.
70192
+ * @param {string} [backdropFilter] What that wash does to the picture
70193
+ * underneath (`"blur(4px)"`), independently of what a click outside does.
70194
+ * See Dialog's own doc.
69916
70195
  * @param {number|string} [marginWithContainer] Minimum gap kept between the
69917
70196
  * popup and the edges of what contains it (the viewport, or the picker's own
69918
70197
  * positioned ancestor for `popupLayer="local"`). Caps the popup's size as
@@ -72324,6 +72603,8 @@ const css$n = /* css */`.navi_split_button {
72324
72603
  * dockedOnSmallTouchScreen?: boolean,
72325
72604
  * marginWithContainer?: number | string,
72326
72605
  * backdropVariant?: "auto" | "discrete" | "invisible",
72606
+ * backdropColor?: string,
72607
+ * backdropFilter?: string,
72327
72608
  * pointerInteractionOutsideEffect?: "close" | "cancel" | "capture",
72328
72609
  * escapeEffect?: "cancel" | "close",
72329
72610
  * popupLayer?: "top" | "local",
@@ -72370,6 +72651,7 @@ const css$n = /* css */`.navi_split_button {
72370
72651
  * `dialogMaxWidth`/`Height`,
72371
72652
  * `marginWithContainer`, `popoverMode`, `popoverSpacing`, `popupLayer`,
72372
72653
  * `popupTestId`, `popupWidthFitContent`, `popoverMaxHeight`, `backdropVariant`,
72654
+ * `backdropColor`, `backdropFilter`,
72373
72655
  * `pointerInteractionOutsideEffect`, `escapeEffect`, `closeOnFocusOut`,
72374
72656
  * `scrollCapture`, `focusCapture`, `popupBackgroundColor`,
72375
72657
  * `popupBorderRadius`, `animation`. See picker.jsx for what each one says.
@@ -72570,7 +72852,7 @@ const SplitButton = props => {
72570
72852
  // What the Picker's popup answers to — Picker's own popup props, named here so
72571
72853
  // a caller reaches all of them through the split button (see picker.jsx's JSDoc
72572
72854
  // for what each one says).
72573
- const POPUP_PROP_SET = new Set(["mode", "popupLayer", "popupTestId", "positionArea", "popoverMode", "popoverSpacing", "popupWidthFitContent", "popoverMaxHeight", "dialogMinWidth", "dialogMinHeight", "dialogMaxWidth", "dialogMaxHeight", "dialogExpand", "dialogExpandX", "dialogExpandY", "dockedOnSmallTouchScreen", "marginWithContainer", "backdropVariant", "pointerInteractionOutsideEffect", "escapeEffect", "closeOnFocusOut", "scrollCapture", "focusCapture", "popupBackgroundColor", "popupBorderRadius", "animation"]);
72855
+ const POPUP_PROP_SET = new Set(["mode", "popupLayer", "popupTestId", "positionArea", "popoverMode", "popoverSpacing", "popupWidthFitContent", "popoverMaxHeight", "dialogMinWidth", "dialogMinHeight", "dialogMaxWidth", "dialogMaxHeight", "dialogExpand", "dialogExpandX", "dialogExpandY", "dockedOnSmallTouchScreen", "marginWithContainer", "backdropVariant", "backdropColor", "backdropFilter", "pointerInteractionOutsideEffect", "escapeEffect", "closeOnFocusOut", "scrollCapture", "focusCapture", "popupBackgroundColor", "popupBorderRadius", "animation"]);
72574
72856
  const splitPopupProps = props => {
72575
72857
  const popupProps = {};
72576
72858
  const boxProps = {};