@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/dev/jsenv_navi.js
CHANGED
|
@@ -50338,10 +50338,10 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50338
50338
|
}
|
|
50339
50339
|
|
|
50340
50340
|
& > .navi_expandable_content_container {
|
|
50341
|
-
clip-path: inset(-9999px -9999px 0);
|
|
50342
50341
|
grid-template-rows: 0fr;
|
|
50343
50342
|
display: grid;
|
|
50344
50343
|
position: relative;
|
|
50344
|
+
overflow-y: clip;
|
|
50345
50345
|
|
|
50346
50346
|
& > .navi_expandable_content_sizer {
|
|
50347
50347
|
min-height: 0;
|
|
@@ -50354,7 +50354,6 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50354
50354
|
}
|
|
50355
50355
|
|
|
50356
50356
|
&[data-open-direction="up"] > .navi_expandable_content_container {
|
|
50357
|
-
clip-path: inset(0 -9999px -9999px);
|
|
50358
50357
|
align-content: end;
|
|
50359
50358
|
|
|
50360
50359
|
& > .navi_expandable_content_sizer {
|
|
@@ -50376,9 +50375,9 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50376
50375
|
}
|
|
50377
50376
|
|
|
50378
50377
|
& > .navi_expandable_content_container {
|
|
50379
|
-
clip-path: inset(-9999px 0 0 -9999px);
|
|
50380
50378
|
grid-template-rows: 0fr;
|
|
50381
50379
|
grid-template-columns: 0fr;
|
|
50380
|
+
overflow: clip;
|
|
50382
50381
|
|
|
50383
50382
|
& > .navi_expandable_content_sizer {
|
|
50384
50383
|
min-width: 0;
|
|
@@ -50396,7 +50395,6 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50396
50395
|
}
|
|
50397
50396
|
|
|
50398
50397
|
&[data-open-direction="left"] > .navi_expandable_content_container {
|
|
50399
|
-
clip-path: inset(-9999px -9999px 0 0);
|
|
50400
50398
|
justify-content: end;
|
|
50401
50399
|
|
|
50402
50400
|
& > .navi_expandable_content_sizer {
|
|
@@ -50418,11 +50416,10 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50418
50416
|
}
|
|
50419
50417
|
|
|
50420
50418
|
&[aria-expanded="true"][data-settled] > .navi_expandable_content_container {
|
|
50421
|
-
|
|
50419
|
+
overflow: visible;
|
|
50422
50420
|
}
|
|
50423
50421
|
|
|
50424
50422
|
&:not([aria-expanded="true"])[data-settled] > .navi_expandable_content_container {
|
|
50425
|
-
clip-path: none;
|
|
50426
50423
|
overflow: clip;
|
|
50427
50424
|
}
|
|
50428
50425
|
|
|
@@ -50519,11 +50516,12 @@ const useExpandableContext = partName => {
|
|
|
50519
50516
|
* that can scroll so the content revealed past its edge is on screen: an
|
|
50520
50517
|
* expandable opening at the bottom of a list otherwise grows below the
|
|
50521
50518
|
* fold, and the user sees the row grow but not what it grew with. Measured
|
|
50522
|
-
* on the open layout
|
|
50523
|
-
*
|
|
50524
|
-
*
|
|
50525
|
-
*
|
|
50526
|
-
*
|
|
50519
|
+
* on the open layout, once per opening; when `animation` plays the
|
|
50520
|
+
* scroller rides along with the reveal, at the track's own progress, and
|
|
50521
|
+
* otherwise it goes there at once. A `scroll-margin` on the expandable is
|
|
50522
|
+
* honored. An expandable taller than the scroller keeps its UI part on
|
|
50523
|
+
* screen and the content follows as far as it fits. Only the nearest
|
|
50524
|
+
* scroller moves — a popup or a page around it stays where it is.
|
|
50527
50525
|
* @param maxContentHeight - Caps the content height; taller content scrolls
|
|
50528
50526
|
* inside the expandable instead of growing it.
|
|
50529
50527
|
* @param mount - When the content is built and thrown away, a popup's own
|
|
@@ -50646,15 +50644,27 @@ const Expandable = props => {
|
|
|
50646
50644
|
cancelSettleWatchRef.current?.();
|
|
50647
50645
|
cancelSettleWatchRef.current = null;
|
|
50648
50646
|
};
|
|
50649
|
-
|
|
50647
|
+
// `stopRide`, when the scroller rides along with the reveal (keepInView):
|
|
50648
|
+
// the ride is part of the movement, so it ends with it — settled or
|
|
50649
|
+
// cancelled — and never on its own clock.
|
|
50650
|
+
const watchSettle = stopRide => {
|
|
50650
50651
|
const contentContainer = contentContainerRef.current;
|
|
50651
50652
|
const contentElement = contentContainer.firstElementChild.firstElementChild;
|
|
50652
|
-
|
|
50653
|
+
const cancelWatch = whenTransitionSettles(contentContainer, () => {
|
|
50653
50654
|
cancelSettleWatchRef.current = null;
|
|
50655
|
+
if (stopRide) {
|
|
50656
|
+
stopRide();
|
|
50657
|
+
}
|
|
50654
50658
|
contentElement.style.width = "";
|
|
50655
50659
|
contentElement.style.height = "";
|
|
50656
50660
|
setSettled(true);
|
|
50657
50661
|
});
|
|
50662
|
+
cancelSettleWatchRef.current = () => {
|
|
50663
|
+
if (stopRide) {
|
|
50664
|
+
stopRide();
|
|
50665
|
+
}
|
|
50666
|
+
cancelWatch();
|
|
50667
|
+
};
|
|
50658
50668
|
};
|
|
50659
50669
|
|
|
50660
50670
|
// The reveal needs the content at its final size before the track starts
|
|
@@ -50673,17 +50683,22 @@ const Expandable = props => {
|
|
|
50673
50683
|
} else {
|
|
50674
50684
|
contentElement.style.height = `${finalRect.height}px`;
|
|
50675
50685
|
}
|
|
50686
|
+
let stopRide = null;
|
|
50676
50687
|
if (keepInView) {
|
|
50677
|
-
//
|
|
50678
|
-
// this point, so where the content ends is known before the
|
|
50679
|
-
// starts
|
|
50680
|
-
//
|
|
50681
|
-
|
|
50682
|
-
|
|
50683
|
-
|
|
50684
|
-
|
|
50685
|
-
|
|
50686
|
-
|
|
50688
|
+
// Measured here and not once the reveal settles: the layout is the open
|
|
50689
|
+
// one at this point, so where the content ends is known before the
|
|
50690
|
+
// movement starts. The scroll then rides the movement rather than
|
|
50691
|
+
// running ahead of it (see rideScrollerAlongReveal).
|
|
50692
|
+
const revealScroll = measureRevealScroll(rootRef.current, revealDirection);
|
|
50693
|
+
if (revealScroll) {
|
|
50694
|
+
const finalContainerRect = contentContainer.getBoundingClientRect();
|
|
50695
|
+
stopRide = rideScrollerAlongReveal(revealScroll, {
|
|
50696
|
+
contentContainer,
|
|
50697
|
+
axis: isColumn ? "x" : "y",
|
|
50698
|
+
startSize: isColumn ? startRect.width : startRect.height,
|
|
50699
|
+
finalSize: isColumn ? finalContainerRect.width : finalContainerRect.height
|
|
50700
|
+
});
|
|
50701
|
+
}
|
|
50687
50702
|
}
|
|
50688
50703
|
// Put the tracks back where the last paint left them and let the
|
|
50689
50704
|
// transition play from there. In fr — px does not interpolate with fr.
|
|
@@ -50706,6 +50721,7 @@ const Expandable = props => {
|
|
|
50706
50721
|
contentContainer.style.transitionProperty = "";
|
|
50707
50722
|
contentContainer.style.gridTemplateColumns = "";
|
|
50708
50723
|
contentContainer.style.gridTemplateRows = "";
|
|
50724
|
+
return stopRide;
|
|
50709
50725
|
};
|
|
50710
50726
|
|
|
50711
50727
|
// What opening LOOKS like here, and how to undo it — the one thing an
|
|
@@ -50737,12 +50753,17 @@ const Expandable = props => {
|
|
|
50737
50753
|
// transfer there is nothing to restore on close either.
|
|
50738
50754
|
const restoreFocus = autoFocus && !silent && contentContainer ? openController.transferFocusOnOpen(contentContainer) : null;
|
|
50739
50755
|
if (revealing) {
|
|
50740
|
-
armReveal(startRect);
|
|
50741
|
-
watchSettle();
|
|
50756
|
+
const stopRide = armReveal(startRect);
|
|
50757
|
+
watchSettle(stopRide);
|
|
50742
50758
|
} else if (keepInView && !silent && contentContainer) {
|
|
50743
|
-
|
|
50744
|
-
|
|
50745
|
-
|
|
50759
|
+
const revealScroll = measureRevealScroll(rootRef.current, revealDirection);
|
|
50760
|
+
if (revealScroll) {
|
|
50761
|
+
// No behavior: the scroller's own scroll-behavior decides.
|
|
50762
|
+
revealScroll.scrollerEl.scrollTo({
|
|
50763
|
+
left: revealScroll.left,
|
|
50764
|
+
top: revealScroll.top
|
|
50765
|
+
});
|
|
50766
|
+
}
|
|
50746
50767
|
}
|
|
50747
50768
|
if (!silent) {
|
|
50748
50769
|
rootRef.current.dispatchEvent(createToggleEvent(true));
|
|
@@ -50784,7 +50805,7 @@ const Expandable = props => {
|
|
|
50784
50805
|
}
|
|
50785
50806
|
}
|
|
50786
50807
|
if (collapsing) {
|
|
50787
|
-
watchSettle();
|
|
50808
|
+
watchSettle(null);
|
|
50788
50809
|
}
|
|
50789
50810
|
rootRef.current.dispatchEvent(createToggleEvent(false));
|
|
50790
50811
|
};
|
|
@@ -51124,16 +51145,14 @@ Expandable.Content = ExpandableContent;
|
|
|
51124
51145
|
// the one exception, excluded at the call site.
|
|
51125
51146
|
const UI_INTERACTIVE_SELECTOR = ["a[href]", "button", "input", "select", "textarea", "label", "[role='button']", "[contenteditable='']", "[contenteditable='true']", "audio[controls]", "video[controls]"].join(", ");
|
|
51126
51147
|
|
|
51127
|
-
//
|
|
51128
|
-
// part and revealed content —
|
|
51129
|
-
// so the caller
|
|
51130
|
-
// openEffect). A root taller than the view is aligned on
|
|
51131
|
-
// what the user pressed stays on screen, and the content
|
|
51132
|
-
// fits. One scroller only — a popup or a page around it
|
|
51133
|
-
|
|
51134
|
-
|
|
51135
|
-
behavior
|
|
51136
|
-
}) => {
|
|
51148
|
+
// Where the nearest scroller that can scroll would have to be for the whole
|
|
51149
|
+
// expandable — UI part and revealed content — to be in view. Measured on the
|
|
51150
|
+
// layout as it stands, so the caller measures while the open layout is the
|
|
51151
|
+
// one laid out (see openEffect). A root taller than the view is aligned on
|
|
51152
|
+
// its UI side instead: what the user pressed stays on screen, and the content
|
|
51153
|
+
// follows as far as it fits. One scroller only — a popup or a page around it
|
|
51154
|
+
// is left where it is. Null when there is no scroller, or nothing to scroll.
|
|
51155
|
+
const measureRevealScroll = (rootEl, revealDirection) => {
|
|
51137
51156
|
let scrollerEl = null;
|
|
51138
51157
|
for (const scrollContainer of getScrollContainerSet(rootEl)) {
|
|
51139
51158
|
if (isScrollable(scrollContainer)) {
|
|
@@ -51142,7 +51161,7 @@ const scrollExpandableIntoView = (rootEl, {
|
|
|
51142
51161
|
}
|
|
51143
51162
|
}
|
|
51144
51163
|
if (!scrollerEl) {
|
|
51145
|
-
return;
|
|
51164
|
+
return null;
|
|
51146
51165
|
}
|
|
51147
51166
|
const rootRect = rootEl.getBoundingClientRect();
|
|
51148
51167
|
let block = "nearest";
|
|
@@ -51154,12 +51173,74 @@ const scrollExpandableIntoView = (rootEl, {
|
|
|
51154
51173
|
} else if (rootRect.width > scrollerEl.clientWidth) {
|
|
51155
51174
|
inline = revealDirection === "right" ? "start" : "end";
|
|
51156
51175
|
}
|
|
51157
|
-
|
|
51176
|
+
const {
|
|
51177
|
+
left,
|
|
51178
|
+
top
|
|
51179
|
+
} = getScrollIntoViewScopedOffsets(rootEl, {
|
|
51158
51180
|
container: scrollerEl,
|
|
51159
51181
|
block,
|
|
51160
|
-
inline
|
|
51161
|
-
behavior
|
|
51182
|
+
inline
|
|
51162
51183
|
});
|
|
51184
|
+
if (left === scrollerEl.scrollLeft && top === scrollerEl.scrollTop) {
|
|
51185
|
+
return null;
|
|
51186
|
+
}
|
|
51187
|
+
return {
|
|
51188
|
+
scrollerEl,
|
|
51189
|
+
left,
|
|
51190
|
+
top
|
|
51191
|
+
};
|
|
51192
|
+
};
|
|
51193
|
+
|
|
51194
|
+
// Moves the scroller toward where the reveal ends at the pace of the reveal
|
|
51195
|
+
// itself: every frame the track's progress is read from the container's size
|
|
51196
|
+
// and the scroll stands the same fraction of its own way. The scroll cannot
|
|
51197
|
+
// run ahead of the track: only the box's own growth extends the scroller's
|
|
51198
|
+
// range, and what the target adds around the box (a parent's padding, a
|
|
51199
|
+
// scroll-margin) becomes reachable as the track grows — a scroll started at
|
|
51200
|
+
// once would be clamped short of it. One clock, the transition's, so the
|
|
51201
|
+
// content never waits below the fold either. Returns what stops the ride.
|
|
51202
|
+
const rideScrollerAlongReveal = ({
|
|
51203
|
+
scrollerEl,
|
|
51204
|
+
left,
|
|
51205
|
+
top
|
|
51206
|
+
}, {
|
|
51207
|
+
contentContainer,
|
|
51208
|
+
axis,
|
|
51209
|
+
startSize,
|
|
51210
|
+
finalSize
|
|
51211
|
+
}) => {
|
|
51212
|
+
const startLeft = scrollerEl.scrollLeft;
|
|
51213
|
+
const startTop = scrollerEl.scrollTop;
|
|
51214
|
+
const leftDelta = left - startLeft;
|
|
51215
|
+
const topDelta = top - startTop;
|
|
51216
|
+
let frameId;
|
|
51217
|
+
const tick = () => {
|
|
51218
|
+
const rect = contentContainer.getBoundingClientRect();
|
|
51219
|
+
const size = axis === "x" ? rect.width : rect.height;
|
|
51220
|
+
let progress = 1;
|
|
51221
|
+
if (finalSize !== startSize) {
|
|
51222
|
+
progress = (size - startSize) / (finalSize - startSize);
|
|
51223
|
+
if (progress < 0) {
|
|
51224
|
+
progress = 0;
|
|
51225
|
+
} else if (progress > 1) {
|
|
51226
|
+
progress = 1;
|
|
51227
|
+
}
|
|
51228
|
+
}
|
|
51229
|
+
scrollerEl.scrollTo({
|
|
51230
|
+
left: startLeft + leftDelta * progress,
|
|
51231
|
+
top: startTop + topDelta * progress,
|
|
51232
|
+
// Driven frame by frame: a smooth scroll-behavior on the scroller is
|
|
51233
|
+
// for a scroll that lands, not for one that is held.
|
|
51234
|
+
behavior: "instant"
|
|
51235
|
+
});
|
|
51236
|
+
if (progress < 1) {
|
|
51237
|
+
frameId = requestAnimationFrame(tick);
|
|
51238
|
+
}
|
|
51239
|
+
};
|
|
51240
|
+
frameId = requestAnimationFrame(tick);
|
|
51241
|
+
return () => {
|
|
51242
|
+
cancelAnimationFrame(frameId);
|
|
51243
|
+
};
|
|
51163
51244
|
};
|
|
51164
51245
|
const createToggleEvent = open => {
|
|
51165
51246
|
const newState = open ? "open" : "closed";
|