@jsenv/navi 0.29.390 → 0.29.391
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/dev/jsenv_navi.js +124 -43
- package/dist/dev/jsenv_navi.js.map +2 -2
- package/dist/jsenv_navi.js +124 -43
- package/dist/jsenv_navi.js.map +2 -2
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -49208,10 +49208,10 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49208
49208
|
}
|
|
49209
49209
|
|
|
49210
49210
|
& > .navi_expandable_content_container {
|
|
49211
|
-
clip-path: inset(-9999px -9999px 0);
|
|
49212
49211
|
grid-template-rows: 0fr;
|
|
49213
49212
|
display: grid;
|
|
49214
49213
|
position: relative;
|
|
49214
|
+
overflow-y: clip;
|
|
49215
49215
|
|
|
49216
49216
|
& > .navi_expandable_content_sizer {
|
|
49217
49217
|
min-height: 0;
|
|
@@ -49224,7 +49224,6 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49224
49224
|
}
|
|
49225
49225
|
|
|
49226
49226
|
&[data-open-direction="up"] > .navi_expandable_content_container {
|
|
49227
|
-
clip-path: inset(0 -9999px -9999px);
|
|
49228
49227
|
align-content: end;
|
|
49229
49228
|
|
|
49230
49229
|
& > .navi_expandable_content_sizer {
|
|
@@ -49246,9 +49245,9 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49246
49245
|
}
|
|
49247
49246
|
|
|
49248
49247
|
& > .navi_expandable_content_container {
|
|
49249
|
-
clip-path: inset(-9999px 0 0 -9999px);
|
|
49250
49248
|
grid-template-rows: 0fr;
|
|
49251
49249
|
grid-template-columns: 0fr;
|
|
49250
|
+
overflow: clip;
|
|
49252
49251
|
|
|
49253
49252
|
& > .navi_expandable_content_sizer {
|
|
49254
49253
|
min-width: 0;
|
|
@@ -49266,7 +49265,6 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49266
49265
|
}
|
|
49267
49266
|
|
|
49268
49267
|
&[data-open-direction="left"] > .navi_expandable_content_container {
|
|
49269
|
-
clip-path: inset(-9999px -9999px 0 0);
|
|
49270
49268
|
justify-content: end;
|
|
49271
49269
|
|
|
49272
49270
|
& > .navi_expandable_content_sizer {
|
|
@@ -49288,11 +49286,10 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49288
49286
|
}
|
|
49289
49287
|
|
|
49290
49288
|
&[aria-expanded="true"][data-settled] > .navi_expandable_content_container {
|
|
49291
|
-
|
|
49289
|
+
overflow: visible;
|
|
49292
49290
|
}
|
|
49293
49291
|
|
|
49294
49292
|
&:not([aria-expanded="true"])[data-settled] > .navi_expandable_content_container {
|
|
49295
|
-
clip-path: none;
|
|
49296
49293
|
overflow: clip;
|
|
49297
49294
|
}
|
|
49298
49295
|
|
|
@@ -49389,11 +49386,12 @@ const useExpandableContext = partName => {
|
|
|
49389
49386
|
* that can scroll so the content revealed past its edge is on screen: an
|
|
49390
49387
|
* expandable opening at the bottom of a list otherwise grows below the
|
|
49391
49388
|
* fold, and the user sees the row grow but not what it grew with. Measured
|
|
49392
|
-
* on the open layout
|
|
49393
|
-
*
|
|
49394
|
-
*
|
|
49395
|
-
*
|
|
49396
|
-
*
|
|
49389
|
+
* on the open layout, once per opening; when `animation` plays the
|
|
49390
|
+
* scroller rides along with the reveal, at the track's own progress, and
|
|
49391
|
+
* otherwise it goes there at once. A `scroll-margin` on the expandable is
|
|
49392
|
+
* honored. An expandable taller than the scroller keeps its UI part on
|
|
49393
|
+
* screen and the content follows as far as it fits. Only the nearest
|
|
49394
|
+
* scroller moves — a popup or a page around it stays where it is.
|
|
49397
49395
|
* @param maxContentHeight - Caps the content height; taller content scrolls
|
|
49398
49396
|
* inside the expandable instead of growing it.
|
|
49399
49397
|
* @param mount - When the content is built and thrown away, a popup's own
|
|
@@ -49516,15 +49514,27 @@ const Expandable = props => {
|
|
|
49516
49514
|
cancelSettleWatchRef.current?.();
|
|
49517
49515
|
cancelSettleWatchRef.current = null;
|
|
49518
49516
|
};
|
|
49519
|
-
|
|
49517
|
+
// `stopRide`, when the scroller rides along with the reveal (keepInView):
|
|
49518
|
+
// the ride is part of the movement, so it ends with it — settled or
|
|
49519
|
+
// cancelled — and never on its own clock.
|
|
49520
|
+
const watchSettle = stopRide => {
|
|
49520
49521
|
const contentContainer = contentContainerRef.current;
|
|
49521
49522
|
const contentElement = contentContainer.firstElementChild.firstElementChild;
|
|
49522
|
-
|
|
49523
|
+
const cancelWatch = whenTransitionSettles(contentContainer, () => {
|
|
49523
49524
|
cancelSettleWatchRef.current = null;
|
|
49525
|
+
if (stopRide) {
|
|
49526
|
+
stopRide();
|
|
49527
|
+
}
|
|
49524
49528
|
contentElement.style.width = "";
|
|
49525
49529
|
contentElement.style.height = "";
|
|
49526
49530
|
setSettled(true);
|
|
49527
49531
|
});
|
|
49532
|
+
cancelSettleWatchRef.current = () => {
|
|
49533
|
+
if (stopRide) {
|
|
49534
|
+
stopRide();
|
|
49535
|
+
}
|
|
49536
|
+
cancelWatch();
|
|
49537
|
+
};
|
|
49528
49538
|
};
|
|
49529
49539
|
|
|
49530
49540
|
// The reveal needs the content at its final size before the track starts
|
|
@@ -49543,17 +49553,22 @@ const Expandable = props => {
|
|
|
49543
49553
|
} else {
|
|
49544
49554
|
contentElement.style.height = `${finalRect.height}px`;
|
|
49545
49555
|
}
|
|
49556
|
+
let stopRide = null;
|
|
49546
49557
|
if (keepInView) {
|
|
49547
|
-
//
|
|
49548
|
-
// this point, so where the content ends is known before the
|
|
49549
|
-
// starts
|
|
49550
|
-
//
|
|
49551
|
-
|
|
49552
|
-
|
|
49553
|
-
|
|
49554
|
-
|
|
49555
|
-
|
|
49556
|
-
|
|
49558
|
+
// Measured here and not once the reveal settles: the layout is the open
|
|
49559
|
+
// one at this point, so where the content ends is known before the
|
|
49560
|
+
// movement starts. The scroll then rides the movement rather than
|
|
49561
|
+
// running ahead of it (see rideScrollerAlongReveal).
|
|
49562
|
+
const revealScroll = measureRevealScroll(rootRef.current, revealDirection);
|
|
49563
|
+
if (revealScroll) {
|
|
49564
|
+
const finalContainerRect = contentContainer.getBoundingClientRect();
|
|
49565
|
+
stopRide = rideScrollerAlongReveal(revealScroll, {
|
|
49566
|
+
contentContainer,
|
|
49567
|
+
axis: isColumn ? "x" : "y",
|
|
49568
|
+
startSize: isColumn ? startRect.width : startRect.height,
|
|
49569
|
+
finalSize: isColumn ? finalContainerRect.width : finalContainerRect.height
|
|
49570
|
+
});
|
|
49571
|
+
}
|
|
49557
49572
|
}
|
|
49558
49573
|
// Put the tracks back where the last paint left them and let the
|
|
49559
49574
|
// transition play from there. In fr — px does not interpolate with fr.
|
|
@@ -49576,6 +49591,7 @@ const Expandable = props => {
|
|
|
49576
49591
|
contentContainer.style.transitionProperty = "";
|
|
49577
49592
|
contentContainer.style.gridTemplateColumns = "";
|
|
49578
49593
|
contentContainer.style.gridTemplateRows = "";
|
|
49594
|
+
return stopRide;
|
|
49579
49595
|
};
|
|
49580
49596
|
|
|
49581
49597
|
// What opening LOOKS like here, and how to undo it — the one thing an
|
|
@@ -49607,12 +49623,17 @@ const Expandable = props => {
|
|
|
49607
49623
|
// transfer there is nothing to restore on close either.
|
|
49608
49624
|
const restoreFocus = autoFocus && !silent && contentContainer ? openController.transferFocusOnOpen(contentContainer) : null;
|
|
49609
49625
|
if (revealing) {
|
|
49610
|
-
armReveal(startRect);
|
|
49611
|
-
watchSettle();
|
|
49626
|
+
const stopRide = armReveal(startRect);
|
|
49627
|
+
watchSettle(stopRide);
|
|
49612
49628
|
} else if (keepInView && !silent && contentContainer) {
|
|
49613
|
-
|
|
49614
|
-
|
|
49615
|
-
|
|
49629
|
+
const revealScroll = measureRevealScroll(rootRef.current, revealDirection);
|
|
49630
|
+
if (revealScroll) {
|
|
49631
|
+
// No behavior: the scroller's own scroll-behavior decides.
|
|
49632
|
+
revealScroll.scrollerEl.scrollTo({
|
|
49633
|
+
left: revealScroll.left,
|
|
49634
|
+
top: revealScroll.top
|
|
49635
|
+
});
|
|
49636
|
+
}
|
|
49616
49637
|
}
|
|
49617
49638
|
if (!silent) {
|
|
49618
49639
|
rootRef.current.dispatchEvent(createToggleEvent(true));
|
|
@@ -49654,7 +49675,7 @@ const Expandable = props => {
|
|
|
49654
49675
|
}
|
|
49655
49676
|
}
|
|
49656
49677
|
if (collapsing) {
|
|
49657
|
-
watchSettle();
|
|
49678
|
+
watchSettle(null);
|
|
49658
49679
|
}
|
|
49659
49680
|
rootRef.current.dispatchEvent(createToggleEvent(false));
|
|
49660
49681
|
};
|
|
@@ -49994,16 +50015,14 @@ Expandable.Content = ExpandableContent;
|
|
|
49994
50015
|
// the one exception, excluded at the call site.
|
|
49995
50016
|
const UI_INTERACTIVE_SELECTOR = ["a[href]", "button", "input", "select", "textarea", "label", "[role='button']", "[contenteditable='']", "[contenteditable='true']", "audio[controls]", "video[controls]"].join(", ");
|
|
49996
50017
|
|
|
49997
|
-
//
|
|
49998
|
-
// part and revealed content —
|
|
49999
|
-
// so the caller
|
|
50000
|
-
// openEffect). A root taller than the view is aligned on
|
|
50001
|
-
// what the user pressed stays on screen, and the content
|
|
50002
|
-
// fits. One scroller only — a popup or a page around it
|
|
50003
|
-
|
|
50004
|
-
|
|
50005
|
-
behavior
|
|
50006
|
-
}) => {
|
|
50018
|
+
// Where the nearest scroller that can scroll would have to be for the whole
|
|
50019
|
+
// expandable — UI part and revealed content — to be in view. Measured on the
|
|
50020
|
+
// layout as it stands, so the caller measures while the open layout is the
|
|
50021
|
+
// one laid out (see openEffect). A root taller than the view is aligned on
|
|
50022
|
+
// its UI side instead: what the user pressed stays on screen, and the content
|
|
50023
|
+
// follows as far as it fits. One scroller only — a popup or a page around it
|
|
50024
|
+
// is left where it is. Null when there is no scroller, or nothing to scroll.
|
|
50025
|
+
const measureRevealScroll = (rootEl, revealDirection) => {
|
|
50007
50026
|
let scrollerEl = null;
|
|
50008
50027
|
for (const scrollContainer of getScrollContainerSet(rootEl)) {
|
|
50009
50028
|
if (isScrollable(scrollContainer)) {
|
|
@@ -50012,7 +50031,7 @@ const scrollExpandableIntoView = (rootEl, {
|
|
|
50012
50031
|
}
|
|
50013
50032
|
}
|
|
50014
50033
|
if (!scrollerEl) {
|
|
50015
|
-
return;
|
|
50034
|
+
return null;
|
|
50016
50035
|
}
|
|
50017
50036
|
const rootRect = rootEl.getBoundingClientRect();
|
|
50018
50037
|
let block = "nearest";
|
|
@@ -50024,12 +50043,74 @@ const scrollExpandableIntoView = (rootEl, {
|
|
|
50024
50043
|
} else if (rootRect.width > scrollerEl.clientWidth) {
|
|
50025
50044
|
inline = revealDirection === "right" ? "start" : "end";
|
|
50026
50045
|
}
|
|
50027
|
-
|
|
50046
|
+
const {
|
|
50047
|
+
left,
|
|
50048
|
+
top
|
|
50049
|
+
} = getScrollIntoViewScopedOffsets(rootEl, {
|
|
50028
50050
|
container: scrollerEl,
|
|
50029
50051
|
block,
|
|
50030
|
-
inline
|
|
50031
|
-
behavior
|
|
50052
|
+
inline
|
|
50032
50053
|
});
|
|
50054
|
+
if (left === scrollerEl.scrollLeft && top === scrollerEl.scrollTop) {
|
|
50055
|
+
return null;
|
|
50056
|
+
}
|
|
50057
|
+
return {
|
|
50058
|
+
scrollerEl,
|
|
50059
|
+
left,
|
|
50060
|
+
top
|
|
50061
|
+
};
|
|
50062
|
+
};
|
|
50063
|
+
|
|
50064
|
+
// Moves the scroller toward where the reveal ends at the pace of the reveal
|
|
50065
|
+
// itself: every frame the track's progress is read from the container's size
|
|
50066
|
+
// and the scroll stands the same fraction of its own way. The scroll cannot
|
|
50067
|
+
// run ahead of the track: only the box's own growth extends the scroller's
|
|
50068
|
+
// range, and what the target adds around the box (a parent's padding, a
|
|
50069
|
+
// scroll-margin) becomes reachable as the track grows — a scroll started at
|
|
50070
|
+
// once would be clamped short of it. One clock, the transition's, so the
|
|
50071
|
+
// content never waits below the fold either. Returns what stops the ride.
|
|
50072
|
+
const rideScrollerAlongReveal = ({
|
|
50073
|
+
scrollerEl,
|
|
50074
|
+
left,
|
|
50075
|
+
top
|
|
50076
|
+
}, {
|
|
50077
|
+
contentContainer,
|
|
50078
|
+
axis,
|
|
50079
|
+
startSize,
|
|
50080
|
+
finalSize
|
|
50081
|
+
}) => {
|
|
50082
|
+
const startLeft = scrollerEl.scrollLeft;
|
|
50083
|
+
const startTop = scrollerEl.scrollTop;
|
|
50084
|
+
const leftDelta = left - startLeft;
|
|
50085
|
+
const topDelta = top - startTop;
|
|
50086
|
+
let frameId;
|
|
50087
|
+
const tick = () => {
|
|
50088
|
+
const rect = contentContainer.getBoundingClientRect();
|
|
50089
|
+
const size = axis === "x" ? rect.width : rect.height;
|
|
50090
|
+
let progress = 1;
|
|
50091
|
+
if (finalSize !== startSize) {
|
|
50092
|
+
progress = (size - startSize) / (finalSize - startSize);
|
|
50093
|
+
if (progress < 0) {
|
|
50094
|
+
progress = 0;
|
|
50095
|
+
} else if (progress > 1) {
|
|
50096
|
+
progress = 1;
|
|
50097
|
+
}
|
|
50098
|
+
}
|
|
50099
|
+
scrollerEl.scrollTo({
|
|
50100
|
+
left: startLeft + leftDelta * progress,
|
|
50101
|
+
top: startTop + topDelta * progress,
|
|
50102
|
+
// Driven frame by frame: a smooth scroll-behavior on the scroller is
|
|
50103
|
+
// for a scroll that lands, not for one that is held.
|
|
50104
|
+
behavior: "instant"
|
|
50105
|
+
});
|
|
50106
|
+
if (progress < 1) {
|
|
50107
|
+
frameId = requestAnimationFrame(tick);
|
|
50108
|
+
}
|
|
50109
|
+
};
|
|
50110
|
+
frameId = requestAnimationFrame(tick);
|
|
50111
|
+
return () => {
|
|
50112
|
+
cancelAnimationFrame(frameId);
|
|
50113
|
+
};
|
|
50033
50114
|
};
|
|
50034
50115
|
const createToggleEvent = open => {
|
|
50035
50116
|
const newState = open ? "open" : "closed";
|