@jsenv/navi 0.29.318 → 0.29.320
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 +211 -64
- package/dist/dev/jsenv_navi.js.map +8 -8
- package/dist/jsenv_navi.js +211 -64
- package/dist/jsenv_navi.js.map +8 -8
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -27017,14 +27017,35 @@ browserIntegration.handleActionTask;
|
|
|
27017
27017
|
|
|
27018
27018
|
const NO_OP = () => {};
|
|
27019
27019
|
const NO_ID_GIVEN = [undefined, NO_OP, NO_OP];
|
|
27020
|
+
// What the computed below answers for a key the document state does not hold:
|
|
27021
|
+
// key presence is the flag, and the value under a present key may be anything,
|
|
27022
|
+
// undefined included.
|
|
27023
|
+
const KEY_NOT_IN_STATE = Symbol("key_not_in_state");
|
|
27020
27024
|
const useNavStateBasic = (
|
|
27021
27025
|
id,
|
|
27022
27026
|
{ debug, type = "replace", onLeave, defaultValue } = {},
|
|
27023
27027
|
) => {
|
|
27024
27028
|
// Hooks must be called unconditionally — before the !id early return.
|
|
27025
|
-
|
|
27026
|
-
//
|
|
27027
|
-
|
|
27029
|
+
//
|
|
27030
|
+
// Subscribed to this one key, through a computed, rather than to the state
|
|
27031
|
+
// as a whole: every popup with a nav state reads here, and a document state
|
|
27032
|
+
// is written whenever any of them opens — a list of forty names each with a
|
|
27033
|
+
// tooltip would re-render forty pickers, chains included, for the sheet
|
|
27034
|
+
// around them opening. The computed only wakes this component when what
|
|
27035
|
+
// sits under its own key changes.
|
|
27036
|
+
const keyValueComputed = useMemo(
|
|
27037
|
+
() =>
|
|
27038
|
+
computed(() => {
|
|
27039
|
+
const state = documentStateSignal.value;
|
|
27040
|
+
if (id && state && Object.hasOwn(state, id)) {
|
|
27041
|
+
return state[id];
|
|
27042
|
+
}
|
|
27043
|
+
return KEY_NOT_IN_STATE;
|
|
27044
|
+
}),
|
|
27045
|
+
[id],
|
|
27046
|
+
);
|
|
27047
|
+
const keyValue = keyValueComputed.value;
|
|
27048
|
+
const keyInState = keyValue !== KEY_NOT_IN_STATE;
|
|
27028
27049
|
const onLeaveRef = useRef(onLeave);
|
|
27029
27050
|
onLeaveRef.current = onLeave;
|
|
27030
27051
|
const prevKeyInStateRef = useRef(keyInState);
|
|
@@ -27054,7 +27075,7 @@ const useNavStateBasic = (
|
|
|
27054
27075
|
effectiveType = "replace";
|
|
27055
27076
|
}
|
|
27056
27077
|
|
|
27057
|
-
const currentValue = keyInState ?
|
|
27078
|
+
const currentValue = keyInState ? keyValue : defaultValue;
|
|
27058
27079
|
|
|
27059
27080
|
if (debug) {
|
|
27060
27081
|
console.debug(`useNavState(${id}) current value is ${currentValue}`);
|
|
@@ -34565,6 +34586,18 @@ const MOUNT_DEFAULT = "from-first-open";
|
|
|
34565
34586
|
const popupsMountingContentForOpen = new Set();
|
|
34566
34587
|
const isMountingContentForOpen = (popupElement) =>
|
|
34567
34588
|
popupsMountingContentForOpen.has(popupElement);
|
|
34589
|
+
// The popup being built that holds `element` somewhere below it, or null. For
|
|
34590
|
+
// an element whose own openable ancestor is something else (a closed trigger
|
|
34591
|
+
// inside the popup): what the layout would say about it is what it says about
|
|
34592
|
+
// the whole popup — nothing is on screen there yet.
|
|
34593
|
+
const findPopupMountingContentAround = (element) => {
|
|
34594
|
+
for (const popupElement of popupsMountingContentForOpen) {
|
|
34595
|
+
if (popupElement !== element && popupElement.contains(element)) {
|
|
34596
|
+
return popupElement;
|
|
34597
|
+
}
|
|
34598
|
+
}
|
|
34599
|
+
return null;
|
|
34600
|
+
};
|
|
34568
34601
|
|
|
34569
34602
|
// requestIdleCallback is missing from Safari; a timeout is close enough there.
|
|
34570
34603
|
const requestIdle = (callback) =>
|
|
@@ -34734,6 +34767,9 @@ const useDisplayedLayoutEffect = (ref, callback, deps) => {
|
|
|
34734
34767
|
// Set by the mount effect below for an element that lives in its openable
|
|
34735
34768
|
// ancestor's façade rather than in what that ancestor opens.
|
|
34736
34769
|
const displayedWhileAncestorClosedRef = useRef(false);
|
|
34770
|
+
// The popup whose opening will answer what the mount could not — see the
|
|
34771
|
+
// mount effect below.
|
|
34772
|
+
const decisionDeferredToRef = useRef(null);
|
|
34737
34773
|
|
|
34738
34774
|
// Run on mount (or when deps change) — but only if the element is visible.
|
|
34739
34775
|
useLayoutEffect(() => {
|
|
@@ -34747,14 +34783,26 @@ const useDisplayedLayoutEffect = (ref, callback, deps) => {
|
|
|
34747
34783
|
return;
|
|
34748
34784
|
}
|
|
34749
34785
|
if (!isAncestorOpen(ancestor)) {
|
|
34750
|
-
if (
|
|
34786
|
+
if (isMountingContentForOpen(ancestor)) {
|
|
34751
34787
|
// The popup building its content for its own opening: nothing in it
|
|
34752
34788
|
// is on screen, and the open about to follow reveals all of it. Known
|
|
34753
34789
|
// without asking the layout, which a synchronous mount would have to
|
|
34754
|
-
// bring up to date once per element asking
|
|
34755
|
-
|
|
34756
|
-
|
|
34757
|
-
|
|
34790
|
+
// bring up to date once per element asking; the observer below fires
|
|
34791
|
+
// once it opens.
|
|
34792
|
+
return;
|
|
34793
|
+
}
|
|
34794
|
+
const popupMounting = findPopupMountingContentAround(el);
|
|
34795
|
+
if (popupMounting) {
|
|
34796
|
+
// Under a closed trigger — a picker's façade, an expandable's header —
|
|
34797
|
+
// inside a popup being built. Whether this element is on screen once
|
|
34798
|
+
// that popup is open is exactly what the layout cannot say while the
|
|
34799
|
+
// popup, and everything in it, is display:none: it would answer "hidden"
|
|
34800
|
+
// for a façade that the opening is about to show. Asked again when the
|
|
34801
|
+
// popup opens (see the observer effect below).
|
|
34802
|
+
decisionDeferredToRef.current = popupMounting;
|
|
34803
|
+
return;
|
|
34804
|
+
}
|
|
34805
|
+
if (!isDisplayedDespiteClosedAncestor(el, ancestor)) {
|
|
34758
34806
|
// Ancestor is closed and took this element off screen with it — skip
|
|
34759
34807
|
// now; the observeAncestorOpenState call below will fire once it
|
|
34760
34808
|
// opens.
|
|
@@ -34778,19 +34826,63 @@ const useDisplayedLayoutEffect = (ref, callback, deps) => {
|
|
|
34778
34826
|
if (!ancestor) {
|
|
34779
34827
|
return undefined;
|
|
34780
34828
|
}
|
|
34781
|
-
|
|
34782
|
-
|
|
34783
|
-
|
|
34784
|
-
|
|
34785
|
-
|
|
34786
|
-
|
|
34787
|
-
|
|
34788
|
-
|
|
34789
|
-
|
|
34790
|
-
|
|
34791
|
-
|
|
34792
|
-
|
|
34793
|
-
|
|
34829
|
+
const stopObservingAncestor = observeAncestorOpenState(
|
|
34830
|
+
ancestor,
|
|
34831
|
+
({ isOpen }) => {
|
|
34832
|
+
if (!isOpen) {
|
|
34833
|
+
return;
|
|
34834
|
+
}
|
|
34835
|
+
if (displayedWhileAncestorClosedRef.current) {
|
|
34836
|
+
// Façade content: on screen the whole time, so this opening reveals
|
|
34837
|
+
// nothing here — and `becauseAncestorOpened: true` about it would be
|
|
34838
|
+
// false in a way consumers act on (see use_auto_focus.js).
|
|
34839
|
+
return;
|
|
34840
|
+
}
|
|
34841
|
+
const lastEl = ref.current;
|
|
34842
|
+
callbackRef.current(lastEl, createDisplayedEvent(ancestor, true));
|
|
34843
|
+
},
|
|
34844
|
+
);
|
|
34845
|
+
const popupMounting = decisionDeferredToRef.current;
|
|
34846
|
+
if (!popupMounting) {
|
|
34847
|
+
return stopObservingAncestor;
|
|
34848
|
+
}
|
|
34849
|
+
// The mount deferred its decision to this popup's opening (see above):
|
|
34850
|
+
// once it is open, the layout answers for what the closed ancestor keeps
|
|
34851
|
+
// on screen. A façade element is then displayed, by that opening — which
|
|
34852
|
+
// owns it, the way it owns everything the popup reveals. An element the
|
|
34853
|
+
// closed ancestor genuinely hides stays with the observer above.
|
|
34854
|
+
const stopObservingPopup = observeAncestorOpenState(
|
|
34855
|
+
popupMounting,
|
|
34856
|
+
({ isOpen }) => {
|
|
34857
|
+
if (!isOpen) {
|
|
34858
|
+
return;
|
|
34859
|
+
}
|
|
34860
|
+
stopObservingPopup();
|
|
34861
|
+
decisionDeferredToRef.current = null;
|
|
34862
|
+
const lastEl = ref.current;
|
|
34863
|
+
if (!lastEl) {
|
|
34864
|
+
return;
|
|
34865
|
+
}
|
|
34866
|
+
if (isAncestorOpen(ancestor)) {
|
|
34867
|
+
callbackRef.current(
|
|
34868
|
+
lastEl,
|
|
34869
|
+
createDisplayedEvent(popupMounting, true),
|
|
34870
|
+
);
|
|
34871
|
+
return;
|
|
34872
|
+
}
|
|
34873
|
+
if (isDisplayedDespiteClosedAncestor(lastEl, ancestor)) {
|
|
34874
|
+
displayedWhileAncestorClosedRef.current = true;
|
|
34875
|
+
callbackRef.current(
|
|
34876
|
+
lastEl,
|
|
34877
|
+
createDisplayedEvent(popupMounting, true),
|
|
34878
|
+
);
|
|
34879
|
+
}
|
|
34880
|
+
},
|
|
34881
|
+
);
|
|
34882
|
+
return () => {
|
|
34883
|
+
stopObservingAncestor();
|
|
34884
|
+
stopObservingPopup();
|
|
34885
|
+
};
|
|
34794
34886
|
}, []);
|
|
34795
34887
|
};
|
|
34796
34888
|
|
|
@@ -60017,24 +60109,18 @@ const useDialogProps = props => {
|
|
|
60017
60109
|
// comment): this opening has its own content to be measured against, and
|
|
60018
60110
|
// measuring it inside last time's box would answer with last time's size.
|
|
60019
60111
|
unfreezeSize(dialogEl);
|
|
60020
|
-
positionDialog();
|
|
60021
|
-
if (sizing === "frozen") {
|
|
60022
|
-
// After positionDialog: the caps it writes
|
|
60023
|
-
// (--container-position-remaining-*) are part of what decides the size
|
|
60024
|
-
// being taken, so measuring before it would freeze a box the dialog
|
|
60025
|
-
// never actually had.
|
|
60026
|
-
freezeSize(dialogEl);
|
|
60027
|
-
}
|
|
60028
60112
|
|
|
60029
|
-
//
|
|
60030
|
-
//
|
|
60031
|
-
//
|
|
60113
|
+
// Placed by the effect's own first check, synchronously, on the opening
|
|
60114
|
+
// event — and repositioned on the same triggers Popover's own
|
|
60115
|
+
// visibleRectEffect reacts to generically: window resize/scroll/
|
|
60116
|
+
// visual-viewport changes for layer="top" (positionedAncestor is already
|
|
60032
60117
|
// document.documentElement there, see its own computation above;
|
|
60033
|
-
// visibleRectEffect already debounces visualViewport resize by 100ms
|
|
60034
|
-
//
|
|
60035
|
-
//
|
|
60036
|
-
//
|
|
60037
|
-
//
|
|
60118
|
+
// visibleRectEffect already debounces visualViewport resize by 100ms to
|
|
60119
|
+
// avoid the mobile tap-to-tap-input keyboard flicker, so no separate
|
|
60120
|
+
// mechanism is needed here for that), or the positioned ancestor's own
|
|
60121
|
+
// resize for layer="local" — see this file's top comment. One placement
|
|
60122
|
+
// for the opening: a positionDialog() of our own before the effect would
|
|
60123
|
+
// be a second pick, and a second layout between two reads of the viewport.
|
|
60038
60124
|
const rectEffect = visibleRectEffect(positionedAncestor, (visibleRect, {
|
|
60039
60125
|
event
|
|
60040
60126
|
}) => {
|
|
@@ -60049,6 +60135,13 @@ const useDialogProps = props => {
|
|
|
60049
60135
|
event: e,
|
|
60050
60136
|
skipElementResize: true
|
|
60051
60137
|
});
|
|
60138
|
+
if (sizing === "frozen") {
|
|
60139
|
+
// After the placement: the caps it writes
|
|
60140
|
+
// (--container-position-remaining-*) are part of what decides the size
|
|
60141
|
+
// being taken, so measuring before it would freeze a box the dialog
|
|
60142
|
+
// never actually had.
|
|
60143
|
+
freezeSize(dialogEl);
|
|
60144
|
+
}
|
|
60052
60145
|
rectEffect.observeSize(dialogEl);
|
|
60053
60146
|
// Exposed for the placement-props effect below, which needs to re-place an
|
|
60054
60147
|
// already-open dialog.
|
|
@@ -62379,6 +62472,13 @@ const PickerCustomResolver = props => {
|
|
|
62379
62472
|
if (props.calloutIcon === undefined) {
|
|
62380
62473
|
props.calloutIcon = props.variant !== "text";
|
|
62381
62474
|
}
|
|
62475
|
+
// A door's content is never where its value comes from (see `standalone`
|
|
62476
|
+
// above), so nothing needs it before the first open: built then, like a
|
|
62477
|
+
// popup's. A name in a list wrapped in a tooltip is otherwise a card in
|
|
62478
|
+
// the DOM per name, and each one asks the layout whether it is on screen.
|
|
62479
|
+
if (props.mount === undefined) {
|
|
62480
|
+
props.mount = MOUNT_DEFAULT;
|
|
62481
|
+
}
|
|
62382
62482
|
if (props.rightSlotIcon === undefined) {
|
|
62383
62483
|
props.rightSlotIcon = jsx(CalloutStatusIcon, {
|
|
62384
62484
|
status: props.calloutStatus,
|
|
@@ -63230,13 +63330,15 @@ const PICKER_CALLOUT_CONTENT_TOKEN = createOpenToken();
|
|
|
63230
63330
|
* The content is rendered into an element this component owns, handed to the
|
|
63231
63331
|
* callout as its message (a Node, appended as-is) and taken back when the
|
|
63232
63332
|
* callout closes. Between two opens it is docked, hidden, in the span below:
|
|
63233
|
-
* in the document the whole time,
|
|
63234
|
-
*
|
|
63235
|
-
*
|
|
63236
|
-
*
|
|
63237
|
-
*
|
|
63238
|
-
*
|
|
63239
|
-
*
|
|
63333
|
+
* in the document the whole time once built, so what it holds survives a
|
|
63334
|
+
* close, and what it measures of itself at mount (a computed color, a
|
|
63335
|
+
* light-dark() pair) resolves against a real ancestry. An element with no
|
|
63336
|
+
* document has no computed style, and a badge reading its own background
|
|
63337
|
+
* there would see nothing at all. When it is built is the popup's own `mount`
|
|
63338
|
+
* rule (see popup_content_mount.js) — the first open, for a callout. The
|
|
63339
|
+
* element carries data-picker-content: the callout is appended inside the
|
|
63340
|
+
* picker root, and a press in there must read as inside the popup, not on the
|
|
63341
|
+
* trigger.
|
|
63240
63342
|
*/
|
|
63241
63343
|
const PickerCalloutPopup = ({
|
|
63242
63344
|
ref,
|
|
@@ -63251,9 +63353,18 @@ const PickerCalloutPopup = ({
|
|
|
63251
63353
|
onnavi_request_open,
|
|
63252
63354
|
onnavi_request_close,
|
|
63253
63355
|
onnavi_request_confirm,
|
|
63254
|
-
|
|
63356
|
+
mount,
|
|
63357
|
+
children: childrenProp
|
|
63255
63358
|
}) => {
|
|
63256
63359
|
const hostRef = useRef(null);
|
|
63360
|
+
// The dock is what the content finds as its openable ancestor (the
|
|
63361
|
+
// aria-expanded below), which is what the mount marks as being built for
|
|
63362
|
+
// its own opening.
|
|
63363
|
+
const contentMounted = usePopupContentMount(openController, ref, {
|
|
63364
|
+
mount,
|
|
63365
|
+
anchor
|
|
63366
|
+
});
|
|
63367
|
+
const children = contentMounted ? childrenProp : null;
|
|
63257
63368
|
// Reassigned on every render, like Popover's own, so it closes over the
|
|
63258
63369
|
// latest props.
|
|
63259
63370
|
openController.getElement = () => pickerRef.current;
|
|
@@ -66134,7 +66245,8 @@ const useListScrollSync = ({
|
|
|
66134
66245
|
const debugScroll = useDebugScroll();
|
|
66135
66246
|
const virtualItemSizeSignal = useVirtualItemSizeSignal(ref, virtualItemSize, horizontal, {
|
|
66136
66247
|
virtual,
|
|
66137
|
-
renderBudget
|
|
66248
|
+
renderBudget,
|
|
66249
|
+
scrolledWanted: scrolled ?? defaultScrolled
|
|
66138
66250
|
});
|
|
66139
66251
|
const getScroller = () => getScrollerEl(ref.current, scroller, horizontal);
|
|
66140
66252
|
const getListEl = () => ref.current.querySelector(".navi_list");
|
|
@@ -67488,7 +67600,8 @@ const measureItemSize = (listEl, horizontal) => {
|
|
|
67488
67600
|
};
|
|
67489
67601
|
const useVirtualItemSizeSignal = (ref, virtualItemSizeProp = 0, horizontal, {
|
|
67490
67602
|
virtual,
|
|
67491
|
-
renderBudget
|
|
67603
|
+
renderBudget,
|
|
67604
|
+
scrolledWanted
|
|
67492
67605
|
}) => {
|
|
67493
67606
|
const virtualSizeSignalRef = useRef(null);
|
|
67494
67607
|
if (!virtualSizeSignalRef.current) {
|
|
@@ -67558,6 +67671,14 @@ const useVirtualItemSizeSignal = (ref, virtualItemSizeProp = 0, horizontal, {
|
|
|
67558
67671
|
if (virtualSizeSignal.peek() !== 0) {
|
|
67559
67672
|
return undefined;
|
|
67560
67673
|
}
|
|
67674
|
+
// Measured only for what reads the size: the fillers of rows held off
|
|
67675
|
+
// screen, and a list held somewhere (placeWhereHeld) before it knows where
|
|
67676
|
+
// that is. A list drawing every row it has, opening at its start, would
|
|
67677
|
+
// pay a layout in every commit for a number nobody reads.
|
|
67678
|
+
const sizeRead = virtual.totalSignal.peek() > renderBudget || scrolledWanted !== undefined && scrolledWanted !== "start";
|
|
67679
|
+
if (!sizeRead) {
|
|
67680
|
+
return undefined;
|
|
67681
|
+
}
|
|
67561
67682
|
const listEl = ref.current?.querySelector(".navi_list");
|
|
67562
67683
|
if (!listEl) {
|
|
67563
67684
|
return undefined;
|
|
@@ -68774,6 +68895,7 @@ const ListItems = ({
|
|
|
68774
68895
|
const virtual = useContext(ListVirtualContext);
|
|
68775
68896
|
const slotId = useContext(ListSlotContext);
|
|
68776
68897
|
const renderWindow = useContext(RenderWindowContext);
|
|
68898
|
+
const separator = useContext(SeparatorContext);
|
|
68777
68899
|
// The vnode drawn for a row, kept by item: a run rendering again (its window
|
|
68778
68900
|
// moving, its first paint's budget giving way to the full one) hands preact
|
|
68779
68901
|
// the same vnode for a row that has not changed, and preact leaves that
|
|
@@ -68782,14 +68904,14 @@ const ListItems = ({
|
|
|
68782
68904
|
// row at the same index, in the same refreshing state: everything the
|
|
68783
68905
|
// function is given.
|
|
68784
68906
|
const rowVnodesRef = useRef(null);
|
|
68785
|
-
if (!rowVnodesRef.current || rowVnodesRef.current.renderItem !== renderItem) {
|
|
68907
|
+
if (!rowVnodesRef.current || rowVnodesRef.current.renderItem !== renderItem || rowVnodesRef.current.separator !== separator) {
|
|
68786
68908
|
rowVnodesRef.current = {
|
|
68787
68909
|
renderItem,
|
|
68910
|
+
separator,
|
|
68788
68911
|
byItem: new Map()
|
|
68789
68912
|
};
|
|
68790
68913
|
}
|
|
68791
68914
|
const rowVnodesByItem = rowVnodesRef.current.byItem;
|
|
68792
|
-
const separator = useContext(SeparatorContext);
|
|
68793
68915
|
const store = useItemStore({
|
|
68794
68916
|
items,
|
|
68795
68917
|
count,
|
|
@@ -69019,17 +69141,33 @@ const ListItems = ({
|
|
|
69019
69141
|
const item = getItemAt(rowIndex);
|
|
69020
69142
|
const key = item === undefined ? `${ownerId}_skeleton_${rowIndex}` : idOf(item, rowIndex);
|
|
69021
69143
|
let rowVnode;
|
|
69144
|
+
let rowContextValue;
|
|
69145
|
+
let rowKept = null;
|
|
69022
69146
|
if (item !== undefined) {
|
|
69023
69147
|
const rowVnodeKept = rowVnodesByItem.get(item);
|
|
69024
69148
|
if (rowVnodeKept && rowVnodeKept.rowIndex === rowIndex && rowVnodeKept.refreshing === renderItemState.refreshing) {
|
|
69025
69149
|
rowVnode = rowVnodeKept.vnode;
|
|
69150
|
+
rowContextValue = rowVnodeKept.rowContextValue;
|
|
69151
|
+
rowKept = rowVnodeKept;
|
|
69026
69152
|
} else {
|
|
69027
69153
|
rowVnode = renderItem(item, rowIndex, renderItemState);
|
|
69028
|
-
|
|
69154
|
+
// Kept with the vnode, for the same reason: a context value that is a
|
|
69155
|
+
// fresh object on every render forces every consumer of it to render,
|
|
69156
|
+
// which is the row's own chain — the vnode handed back unchanged would
|
|
69157
|
+
// then buy nothing.
|
|
69158
|
+
rowContextValue = {
|
|
69159
|
+
id: key,
|
|
69160
|
+
index: rowIndex,
|
|
69161
|
+
item
|
|
69162
|
+
};
|
|
69163
|
+
rowKept = {
|
|
69029
69164
|
vnode: rowVnode,
|
|
69165
|
+
rowContextValue,
|
|
69030
69166
|
rowIndex,
|
|
69031
|
-
refreshing: renderItemState.refreshing
|
|
69032
|
-
|
|
69167
|
+
refreshing: renderItemState.refreshing,
|
|
69168
|
+
separatorVnode: null
|
|
69169
|
+
};
|
|
69170
|
+
rowVnodesByItem.set(item, rowKept);
|
|
69033
69171
|
}
|
|
69034
69172
|
} else if (renderRowSkeleton === false) {
|
|
69035
69173
|
// The row must still take its room: without it the rows below would
|
|
@@ -69053,20 +69191,25 @@ const ListItems = ({
|
|
|
69053
69191
|
// as a hairline under the label.
|
|
69054
69192
|
const drawSeparator = separator && rowIndex > 0 && !opensGroup(groupKeyOf(item, rowIndex));
|
|
69055
69193
|
if (drawSeparator) {
|
|
69056
|
-
|
|
69057
|
-
|
|
69058
|
-
|
|
69194
|
+
// Kept with the row too: a separator built again is a separator
|
|
69195
|
+
// rendered again.
|
|
69196
|
+
let separatorVnode = rowKept ? rowKept.separatorVnode : null;
|
|
69197
|
+
if (!separatorVnode) {
|
|
69198
|
+
separatorVnode = cloneElement(resolveSeparatorVnode(separator, rowIndex - 1), {
|
|
69199
|
+
key: `${key}_separator`
|
|
69200
|
+
});
|
|
69201
|
+
if (rowKept) {
|
|
69202
|
+
rowKept.separatorVnode = separatorVnode;
|
|
69203
|
+
}
|
|
69204
|
+
}
|
|
69205
|
+
pushRow(separatorVnode, item, rowIndex);
|
|
69059
69206
|
}
|
|
69060
69207
|
pushRow(jsx(ListRowContext.Provider, {
|
|
69061
69208
|
value: item === undefined ? {
|
|
69062
69209
|
id: key,
|
|
69063
69210
|
index: rowIndex,
|
|
69064
69211
|
...getSkeletonRow()
|
|
69065
|
-
} :
|
|
69066
|
-
id: key,
|
|
69067
|
-
index: rowIndex,
|
|
69068
|
-
item
|
|
69069
|
-
},
|
|
69212
|
+
} : rowContextValue,
|
|
69070
69213
|
children: rowVnode
|
|
69071
69214
|
}, key), item, rowIndex);
|
|
69072
69215
|
}
|
|
@@ -75264,9 +75407,13 @@ const useSearchText = (searchText, items, matchFn = applySearch) => {
|
|
|
75264
75407
|
return { orderedItems, matchInfoMap };
|
|
75265
75408
|
}, [items, searchText, matchFn]);
|
|
75266
75409
|
|
|
75267
|
-
|
|
75268
|
-
|
|
75269
|
-
|
|
75410
|
+
// The same function for as long as the map is the same: a `renderItem`
|
|
75411
|
+
// reading it is stable only if this is, and a run keeps the rows it drew
|
|
75412
|
+
// only for a stable `renderItem` (see List.Items).
|
|
75413
|
+
const getItemMatchInfo = useCallback(
|
|
75414
|
+
(item) => matchInfoMap.get(item),
|
|
75415
|
+
[matchInfoMap],
|
|
75416
|
+
);
|
|
75270
75417
|
|
|
75271
75418
|
return [orderedItems, getItemMatchInfo];
|
|
75272
75419
|
};
|