@jsenv/navi 0.29.343 → 0.29.344
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 +244 -130
- package/dist/dev/jsenv_navi.js.map +2 -2
- package/dist/jsenv_navi.js +244 -130
- package/dist/jsenv_navi.js.map +2 -2
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -66045,10 +66045,11 @@ const ItemTransitionContext = createContext(false);
|
|
|
66045
66045
|
// that must reserve room for what is not rendered.
|
|
66046
66046
|
const ListVirtualContext = createContext(null);
|
|
66047
66047
|
// Set around each row a run of items renders (see ListItems): which row of the
|
|
66048
|
-
// collection it is,
|
|
66049
|
-
//
|
|
66050
|
-
//
|
|
66051
|
-
//
|
|
66048
|
+
// collection it is, where it stands among the rows the list holds, and the
|
|
66049
|
+
// run's own account of which rows mount (see createRunRows) — what the row
|
|
66050
|
+
// draws its separator from. Carried by context rather than injected into
|
|
66051
|
+
// whatever vnode renderItem returned, so that returning a component of one's
|
|
66052
|
+
// own — instead of a bare <List.Item> — works the same way.
|
|
66052
66053
|
const ListRowContext = createContext(null);
|
|
66053
66054
|
// The slot a child of the list stands in, by id (see ListDeclaredChildren). A
|
|
66054
66055
|
// row takes its place in the collection by slot: the place is then the list's
|
|
@@ -68791,22 +68792,12 @@ const ListItemRowResolver = props => {
|
|
|
68791
68792
|
...props
|
|
68792
68793
|
});
|
|
68793
68794
|
}
|
|
68794
|
-
// eslint-disable-next-line no-unused-vars
|
|
68795
|
-
const {
|
|
68796
|
-
id,
|
|
68797
|
-
index,
|
|
68798
|
-
item,
|
|
68799
|
-
rowMinHeight,
|
|
68800
|
-
rowMinWidth,
|
|
68801
|
-
...rowProps
|
|
68802
|
-
} = row;
|
|
68803
68795
|
return jsx(Next, {
|
|
68804
|
-
...rowProps,
|
|
68805
68796
|
...props,
|
|
68806
68797
|
id: props.id || row.id,
|
|
68807
68798
|
index: row.index,
|
|
68808
|
-
minHeight: props.minHeight === undefined ? rowMinHeight : props.minHeight,
|
|
68809
|
-
minWidth: props.minWidth === undefined ? rowMinWidth : props.minWidth
|
|
68799
|
+
minHeight: props.minHeight === undefined ? row.rowMinHeight : props.minHeight,
|
|
68800
|
+
minWidth: props.minWidth === undefined ? row.rowMinWidth : props.minWidth
|
|
68810
68801
|
});
|
|
68811
68802
|
};
|
|
68812
68803
|
const ListItemPresentationResolver = props => {
|
|
@@ -68884,8 +68875,8 @@ const ListItemUI = props => {
|
|
|
68884
68875
|
const virtual = useContext(ListVirtualContext);
|
|
68885
68876
|
const searchNoMatchMode = useContext(SearchNoMatchModeContext);
|
|
68886
68877
|
// The run this row belongs to, when it comes from one (see ListItems): it
|
|
68887
|
-
// registered the row
|
|
68888
|
-
//
|
|
68878
|
+
// registered the row and decided it is inside the render window. Whether
|
|
68879
|
+
// the row mounts is decided here, and told back to the run.
|
|
68889
68880
|
const row = useContext(ListRowContext);
|
|
68890
68881
|
const slotId = useContext(ListSlotContext);
|
|
68891
68882
|
// There is no standalone match/matchScore/highlight prop — participation
|
|
@@ -68917,16 +68908,24 @@ const ListItemUI = props => {
|
|
|
68917
68908
|
// name of this very component (idDefault, not the row's id): two components
|
|
68918
68909
|
// may stand for the same row for a moment, one leaving as the other arrives,
|
|
68919
68910
|
// and the one leaving must give back its own place, not the newcomer's.
|
|
68920
|
-
if (
|
|
68911
|
+
if (row) {
|
|
68921
68912
|
if (props.filtered) {
|
|
68922
|
-
|
|
68913
|
+
row.run.unmount(idDefault);
|
|
68923
68914
|
} else {
|
|
68924
|
-
|
|
68915
|
+
row.run.mount(idDefault, props.index, row.groupKey);
|
|
68925
68916
|
}
|
|
68917
|
+
} else if (props.filtered) {
|
|
68918
|
+
virtual.drop(idDefault);
|
|
68919
|
+
} else {
|
|
68920
|
+
props.index = virtual.take(idDefault, 1, slotId);
|
|
68926
68921
|
}
|
|
68927
68922
|
useLayoutEffect(() => {
|
|
68928
68923
|
return () => {
|
|
68929
|
-
|
|
68924
|
+
if (row) {
|
|
68925
|
+
row.run.unmount(idDefault);
|
|
68926
|
+
} else {
|
|
68927
|
+
virtual.drop(idDefault);
|
|
68928
|
+
}
|
|
68930
68929
|
};
|
|
68931
68930
|
}, []);
|
|
68932
68931
|
// Every row that is drawn registers itself, whether it was declared one by
|
|
@@ -68940,47 +68939,43 @@ const ListItemUI = props => {
|
|
|
68940
68939
|
if (props.filtered) {
|
|
68941
68940
|
return null;
|
|
68942
68941
|
}
|
|
68943
|
-
// html-hidden items: excluded from virtual scroll accounting but always in DOM
|
|
68944
|
-
if (props.hidden) {
|
|
68945
|
-
// Its separator stays too, and stays invisible with it: the point of
|
|
68946
|
-
// keeping a row that matches nothing is that nothing moves, and a divider
|
|
68947
|
-
// that leaves takes its own height away.
|
|
68948
|
-
if (!separator || props.index === 0) {
|
|
68949
|
-
return jsx(ListItemReal, {
|
|
68950
|
-
...props
|
|
68951
|
-
});
|
|
68952
|
-
}
|
|
68953
|
-
return jsxs(Fragment, {
|
|
68954
|
-
children: [cloneElement(resolveSeparatorVnode(separator, props.index - 1), {
|
|
68955
|
-
style: VISIBILITY_HIDDEN_STYLE
|
|
68956
|
-
}), jsx(ListItemReal, {
|
|
68957
|
-
...props
|
|
68958
|
-
})]
|
|
68959
|
-
});
|
|
68960
|
-
}
|
|
68961
|
-
if (row) {
|
|
68962
|
-
return jsx(ListItemReal, {
|
|
68963
|
-
...props
|
|
68964
|
-
});
|
|
68965
|
-
}
|
|
68966
|
-
const index = props.index;
|
|
68967
68942
|
const listItemVnode = jsx(ListItemReal, {
|
|
68968
68943
|
...props
|
|
68969
68944
|
});
|
|
68970
|
-
|
|
68971
|
-
// out (virtual.take above), not by the tracker's visibleIndex: during a
|
|
68972
|
-
// reorder render pass (items resorted by search score) the other items still
|
|
68973
|
-
// carry stale keyToExplicitOrder values, the binary search reads them, no
|
|
68974
|
-
// item comes out at 0 and a spurious separator appears at the top. Inside a
|
|
68975
|
-
// group, each group has its own tracker and its items do not reorder, so
|
|
68976
|
-
// groupVisibleIndex is reliable.
|
|
68977
|
-
const isFirstInList = groupVisibleIndex === null ? index === 0 : groupVisibleIndex === 0;
|
|
68978
|
-
if (!separator || isFirstInList) {
|
|
68945
|
+
if (!separator) {
|
|
68979
68946
|
return listItemVnode;
|
|
68980
68947
|
}
|
|
68981
|
-
//
|
|
68982
|
-
|
|
68983
|
-
|
|
68948
|
+
// The separator a row wears is the one at the gap above it, so the first row
|
|
68949
|
+
// that mounts wears none. "Am I first?" is answered by whoever handed out
|
|
68950
|
+
// the place — the run for its rows, the list's virtual for a declared one
|
|
68951
|
+
// (virtual.take above) — not by the tracker's visibleIndex: during a reorder
|
|
68952
|
+
// render pass (items resorted by search score) the other items still carry
|
|
68953
|
+
// stale keyToExplicitOrder values, the binary search reads them, no item
|
|
68954
|
+
// comes out at 0 and a spurious separator appears at the top. Inside a
|
|
68955
|
+
// declared group, each group has its own tracker and its items do not
|
|
68956
|
+
// reorder, so groupVisibleIndex is reliable there.
|
|
68957
|
+
let isFirst;
|
|
68958
|
+
if (row) {
|
|
68959
|
+
isFirst = row.run.isFirst(props.index, row.groupKey);
|
|
68960
|
+
} else if (groupVisibleIndex === null || props.hidden) {
|
|
68961
|
+
isFirst = props.index === 0;
|
|
68962
|
+
} else {
|
|
68963
|
+
isFirst = groupVisibleIndex === 0;
|
|
68964
|
+
}
|
|
68965
|
+
if (isFirst) {
|
|
68966
|
+
return listItemVnode;
|
|
68967
|
+
}
|
|
68968
|
+
// The gap index, only used as the function-form argument.
|
|
68969
|
+
const gapIndex = row || groupVisibleIndex === null || props.hidden ? props.index - 1 : groupVisibleIndex - 1;
|
|
68970
|
+
let separatorVnode = resolveSeparatorVnode(separator, gapIndex);
|
|
68971
|
+
if (props.hidden) {
|
|
68972
|
+
// A row kept in the DOM but hidden keeps its separator, hidden with it:
|
|
68973
|
+
// the point of keeping a row that matches nothing is that nothing moves,
|
|
68974
|
+
// and a divider that leaves takes its own height away.
|
|
68975
|
+
separatorVnode = cloneElement(separatorVnode, {
|
|
68976
|
+
style: VISIBILITY_HIDDEN_STYLE
|
|
68977
|
+
});
|
|
68978
|
+
}
|
|
68984
68979
|
return jsxs(Fragment, {
|
|
68985
68980
|
children: [separatorVnode, listItemVnode]
|
|
68986
68981
|
});
|
|
@@ -69602,6 +69597,101 @@ const sameSlotIds = (left, right) => {
|
|
|
69602
69597
|
return true;
|
|
69603
69598
|
};
|
|
69604
69599
|
|
|
69600
|
+
// Which of a run's rows mount, and which of them comes first. A run draws
|
|
69601
|
+
// every row of its window, and only the row itself knows, once it renders,
|
|
69602
|
+
// that it renders nothing (filtered out by a search, see ListItemUI). The
|
|
69603
|
+
// separator a row wears is the one at the gap above it, so the first row that
|
|
69604
|
+
// mounts wears none — and "first" is read off the rows that mount, not off
|
|
69605
|
+
// the collection. Rows say so as they render, in order, and the answer is a
|
|
69606
|
+
// signal: a row rendered from a kept vnode is rendered again when the row
|
|
69607
|
+
// before it leaves or comes back. Grouped rows are counted per group, the gap
|
|
69608
|
+
// above a group's first row being the group wrapper's own.
|
|
69609
|
+
const createRunRows = () => {
|
|
69610
|
+
// rowId → { index, groupKey }
|
|
69611
|
+
const rowById = new Map();
|
|
69612
|
+
// groupKey (undefined outside groups) → the index of the group's first
|
|
69613
|
+
// mounted row, -1 when none.
|
|
69614
|
+
const firstSignalByGroup = new Map();
|
|
69615
|
+
// Where the window starts: a run cut by the window has rows above its first
|
|
69616
|
+
// drawn one, and so does a run standing after declared rows.
|
|
69617
|
+
const windowFromSignal = signal(0);
|
|
69618
|
+
// Groups whose first row left: recounted on the next ask, or at the end of
|
|
69619
|
+
// the frame, whichever comes first.
|
|
69620
|
+
const staleGroupKeys = new Set();
|
|
69621
|
+
const firstSignalOf = groupKey => {
|
|
69622
|
+
let firstSignal = firstSignalByGroup.get(groupKey);
|
|
69623
|
+
if (!firstSignal) {
|
|
69624
|
+
firstSignal = signal(-1);
|
|
69625
|
+
firstSignalByGroup.set(groupKey, firstSignal);
|
|
69626
|
+
}
|
|
69627
|
+
return firstSignal;
|
|
69628
|
+
};
|
|
69629
|
+
const refresh = groupKey => {
|
|
69630
|
+
staleGroupKeys.delete(groupKey);
|
|
69631
|
+
let first = -1;
|
|
69632
|
+
for (const row of rowById.values()) {
|
|
69633
|
+
if (row.groupKey === groupKey && (first === -1 || row.index < first)) {
|
|
69634
|
+
first = row.index;
|
|
69635
|
+
}
|
|
69636
|
+
}
|
|
69637
|
+
firstSignalOf(groupKey).value = first;
|
|
69638
|
+
};
|
|
69639
|
+
const leave = row => {
|
|
69640
|
+
if (firstSignalOf(row.groupKey).peek() !== row.index) {
|
|
69641
|
+
return;
|
|
69642
|
+
}
|
|
69643
|
+
staleGroupKeys.add(row.groupKey);
|
|
69644
|
+
queueMicrotask(() => {
|
|
69645
|
+
if (staleGroupKeys.has(row.groupKey)) {
|
|
69646
|
+
refresh(row.groupKey);
|
|
69647
|
+
}
|
|
69648
|
+
});
|
|
69649
|
+
};
|
|
69650
|
+
return {
|
|
69651
|
+
setWindowFrom: windowFrom => {
|
|
69652
|
+
windowFromSignal.value = windowFrom;
|
|
69653
|
+
},
|
|
69654
|
+
mount: (rowId, index, groupKey) => {
|
|
69655
|
+
const row = rowById.get(rowId);
|
|
69656
|
+
if (row) {
|
|
69657
|
+
if (row.index === index && row.groupKey === groupKey) {
|
|
69658
|
+
return;
|
|
69659
|
+
}
|
|
69660
|
+
leave(row);
|
|
69661
|
+
row.index = index;
|
|
69662
|
+
row.groupKey = groupKey;
|
|
69663
|
+
} else {
|
|
69664
|
+
rowById.set(rowId, {
|
|
69665
|
+
index,
|
|
69666
|
+
groupKey
|
|
69667
|
+
});
|
|
69668
|
+
}
|
|
69669
|
+
const firstSignal = firstSignalOf(groupKey);
|
|
69670
|
+
const first = firstSignal.peek();
|
|
69671
|
+
if (first === -1 || index < first) {
|
|
69672
|
+
firstSignal.value = index;
|
|
69673
|
+
}
|
|
69674
|
+
},
|
|
69675
|
+
unmount: rowId => {
|
|
69676
|
+
const row = rowById.get(rowId);
|
|
69677
|
+
if (!row) {
|
|
69678
|
+
return;
|
|
69679
|
+
}
|
|
69680
|
+
rowById.delete(rowId);
|
|
69681
|
+
leave(row);
|
|
69682
|
+
},
|
|
69683
|
+
isFirst: (index, groupKey) => {
|
|
69684
|
+
if (staleGroupKeys.has(groupKey)) {
|
|
69685
|
+
refresh(groupKey);
|
|
69686
|
+
}
|
|
69687
|
+
if (firstSignalOf(groupKey).value !== index) {
|
|
69688
|
+
return false;
|
|
69689
|
+
}
|
|
69690
|
+
return groupKey !== undefined || windowFromSignal.value === 0;
|
|
69691
|
+
}
|
|
69692
|
+
};
|
|
69693
|
+
};
|
|
69694
|
+
|
|
69605
69695
|
// The walk that gives the list's children their places: a slot for each of
|
|
69606
69696
|
// them, declared to the list's virtual all at once before any child renders,
|
|
69607
69697
|
// and handed to the child through a provider of its own — which is what lets
|
|
@@ -69786,6 +69876,11 @@ const ListItems = ({
|
|
|
69786
69876
|
const slotId = useContext(ListSlotContext);
|
|
69787
69877
|
const renderWindow = useContext(RenderWindowContext);
|
|
69788
69878
|
const separator = useContext(SeparatorContext);
|
|
69879
|
+
const runRowsRef = useRef(null);
|
|
69880
|
+
if (!runRowsRef.current) {
|
|
69881
|
+
runRowsRef.current = createRunRows();
|
|
69882
|
+
}
|
|
69883
|
+
const runRows = runRowsRef.current;
|
|
69789
69884
|
// The vnode drawn for a row, kept by item: a run rendering again (its window
|
|
69790
69885
|
// moving, its first paint's budget giving way to the full one) hands preact
|
|
69791
69886
|
// the same vnode for a row that has not changed, and preact leaves that
|
|
@@ -69794,10 +69889,9 @@ const ListItems = ({
|
|
|
69794
69889
|
// row at the same index, in the same refreshing state: everything the
|
|
69795
69890
|
// function is given.
|
|
69796
69891
|
const rowVnodesRef = useRef(null);
|
|
69797
|
-
if (!rowVnodesRef.current || rowVnodesRef.current.renderItem !== renderItem
|
|
69892
|
+
if (!rowVnodesRef.current || rowVnodesRef.current.renderItem !== renderItem) {
|
|
69798
69893
|
rowVnodesRef.current = {
|
|
69799
69894
|
renderItem,
|
|
69800
|
-
separator,
|
|
69801
69895
|
byItem: new Map()
|
|
69802
69896
|
};
|
|
69803
69897
|
}
|
|
@@ -69846,6 +69940,7 @@ const ListItems = ({
|
|
|
69846
69940
|
const windowFrom = renderWindow.start > runStart ? renderWindow.start : runStart;
|
|
69847
69941
|
const windowTo = renderWindow.end < runEnd ? renderWindow.end : runEnd;
|
|
69848
69942
|
store.forget(rankOf(windowFrom), rankOf(windowTo));
|
|
69943
|
+
runRows.setWindowFrom(windowFrom);
|
|
69849
69944
|
|
|
69850
69945
|
// The row answers to its own id when the item carries one — that is what
|
|
69851
69946
|
// addresses it from outside (--navi-select, --navi-scroll, startAt) — and
|
|
@@ -69969,13 +70064,9 @@ const ListItems = ({
|
|
|
69969
70064
|
}, `${ownerId}_group_${group.key}`));
|
|
69970
70065
|
group = null;
|
|
69971
70066
|
};
|
|
69972
|
-
// Which group a row belongs to, or undefined when it belongs to none.
|
|
69973
|
-
// before the row is pushed as well as while pushing it: a row opening a
|
|
69974
|
-
// group is the one row that must not wear a separator (see below).
|
|
70067
|
+
// Which group a row belongs to, or undefined when it belongs to none.
|
|
69975
70068
|
const groupKeyOf = (item, rowIndex) => groupBy && item !== undefined ? groupBy(item, rowIndex) : undefined;
|
|
69976
|
-
const
|
|
69977
|
-
const pushRow = (rowNode, item, rowIndex) => {
|
|
69978
|
-
const groupKey = groupKeyOf(item, rowIndex);
|
|
70069
|
+
const pushRow = (rowNode, item, rowIndex, groupKey) => {
|
|
69979
70070
|
if (groupKey === undefined) {
|
|
69980
70071
|
closeGroup();
|
|
69981
70072
|
rows.push(rowNode);
|
|
@@ -70030,78 +70121,72 @@ const ListItems = ({
|
|
|
70030
70121
|
}
|
|
70031
70122
|
const item = getItemAt(rowIndex);
|
|
70032
70123
|
const key = item === undefined ? `${ownerId}_skeleton_${rowIndex}` : idOf(item, rowIndex);
|
|
70124
|
+
const groupKey = groupKeyOf(item, rowIndex);
|
|
70125
|
+
if (item === undefined) {
|
|
70126
|
+
// A row on its way never reaches ListItemUI (see ListItemSkeletonResolver):
|
|
70127
|
+
// it is stood among the rows that mount, and given its separator, here.
|
|
70128
|
+
let rowVnode;
|
|
70129
|
+
if (renderRowSkeleton === false) {
|
|
70130
|
+
// The row must still take its room: without it the rows below would
|
|
70131
|
+
// climb up and slide back down as the answer arrives.
|
|
70132
|
+
rowVnode = jsx(ListItem, {
|
|
70133
|
+
skeleton: true,
|
|
70134
|
+
style: VISIBILITY_HIDDEN_STYLE
|
|
70135
|
+
});
|
|
70136
|
+
} else if (renderRowSkeleton) {
|
|
70137
|
+
rowVnode = renderRowSkeleton(rowIndex);
|
|
70138
|
+
} else {
|
|
70139
|
+
rowVnode = jsx(ListItem, {
|
|
70140
|
+
skeleton: true
|
|
70141
|
+
});
|
|
70142
|
+
}
|
|
70143
|
+
if (rowVnode) {
|
|
70144
|
+
pushRow(jsx(ListRunSkeletonRow, {
|
|
70145
|
+
run: runRows,
|
|
70146
|
+
row: {
|
|
70147
|
+
id: key,
|
|
70148
|
+
index: rowIndex,
|
|
70149
|
+
...getSkeletonRow()
|
|
70150
|
+
},
|
|
70151
|
+
groupKey: groupKey,
|
|
70152
|
+
separator: separator,
|
|
70153
|
+
children: rowVnode
|
|
70154
|
+
}, key), item, rowIndex, groupKey);
|
|
70155
|
+
}
|
|
70156
|
+
rowIndex++;
|
|
70157
|
+
continue;
|
|
70158
|
+
}
|
|
70033
70159
|
let rowVnode;
|
|
70034
70160
|
let rowContextValue;
|
|
70035
|
-
|
|
70036
|
-
if (
|
|
70037
|
-
|
|
70038
|
-
|
|
70039
|
-
rowVnode = rowVnodeKept.vnode;
|
|
70040
|
-
rowContextValue = rowVnodeKept.rowContextValue;
|
|
70041
|
-
rowKept = rowVnodeKept;
|
|
70042
|
-
} else {
|
|
70043
|
-
rowVnode = renderItem(item, rowIndex, renderItemState);
|
|
70044
|
-
// Kept with the vnode, for the same reason: a context value that is a
|
|
70045
|
-
// fresh object on every render forces every consumer of it to render,
|
|
70046
|
-
// which is the row's own chain — the vnode handed back unchanged would
|
|
70047
|
-
// then buy nothing.
|
|
70048
|
-
rowContextValue = {
|
|
70049
|
-
id: key,
|
|
70050
|
-
index: rowIndex,
|
|
70051
|
-
item
|
|
70052
|
-
};
|
|
70053
|
-
rowKept = {
|
|
70054
|
-
vnode: rowVnode,
|
|
70055
|
-
rowContextValue,
|
|
70056
|
-
rowIndex,
|
|
70057
|
-
refreshing: renderItemState.refreshing,
|
|
70058
|
-
separatorVnode: null
|
|
70059
|
-
};
|
|
70060
|
-
rowVnodesByItem.set(item, rowKept);
|
|
70061
|
-
}
|
|
70062
|
-
} else if (renderRowSkeleton === false) {
|
|
70063
|
-
// The row must still take its room: without it the rows below would
|
|
70064
|
-
// climb up and slide back down as the answer arrives.
|
|
70065
|
-
rowVnode = jsx(ListItem, {
|
|
70066
|
-
skeleton: true,
|
|
70067
|
-
style: VISIBILITY_HIDDEN_STYLE
|
|
70068
|
-
});
|
|
70069
|
-
} else if (renderRowSkeleton) {
|
|
70070
|
-
rowVnode = renderRowSkeleton(rowIndex);
|
|
70161
|
+
const rowVnodeKept = rowVnodesByItem.get(item);
|
|
70162
|
+
if (rowVnodeKept && rowVnodeKept.rowIndex === rowIndex && rowVnodeKept.refreshing === renderItemState.refreshing && rowVnodeKept.rowContextValue.groupKey === groupKey) {
|
|
70163
|
+
rowVnode = rowVnodeKept.vnode;
|
|
70164
|
+
rowContextValue = rowVnodeKept.rowContextValue;
|
|
70071
70165
|
} else {
|
|
70072
|
-
rowVnode =
|
|
70073
|
-
|
|
70166
|
+
rowVnode = renderItem(item, rowIndex, renderItemState);
|
|
70167
|
+
// Kept with the vnode, for the same reason: a context value that is a
|
|
70168
|
+
// fresh object on every render forces every consumer of it to render,
|
|
70169
|
+
// which is the row's own chain — the vnode handed back unchanged would
|
|
70170
|
+
// then buy nothing.
|
|
70171
|
+
rowContextValue = {
|
|
70172
|
+
id: key,
|
|
70173
|
+
index: rowIndex,
|
|
70174
|
+
item,
|
|
70175
|
+
run: runRows,
|
|
70176
|
+
groupKey
|
|
70177
|
+
};
|
|
70178
|
+
rowVnodesByItem.set(item, {
|
|
70179
|
+
vnode: rowVnode,
|
|
70180
|
+
rowContextValue,
|
|
70181
|
+
rowIndex,
|
|
70182
|
+
refreshing: renderItemState.refreshing
|
|
70074
70183
|
});
|
|
70075
70184
|
}
|
|
70076
70185
|
if (rowVnode) {
|
|
70077
|
-
// The first row of a group wears no separator: the gap it sits at is the
|
|
70078
|
-
// one between two groups, and that gap is the group wrapper's own — it
|
|
70079
|
-
// is a row of the list like any other and draws its separator itself
|
|
70080
|
-
// (see ListItemUI). Drawn here it would land inside the group instead,
|
|
70081
|
-
// as a hairline under the label.
|
|
70082
|
-
const drawSeparator = separator && rowIndex > 0 && !opensGroup(groupKeyOf(item, rowIndex));
|
|
70083
|
-
if (drawSeparator) {
|
|
70084
|
-
// Kept with the row too: a separator built again is a separator
|
|
70085
|
-
// rendered again.
|
|
70086
|
-
let separatorVnode = rowKept ? rowKept.separatorVnode : null;
|
|
70087
|
-
if (!separatorVnode) {
|
|
70088
|
-
separatorVnode = cloneElement(resolveSeparatorVnode(separator, rowIndex - 1), {
|
|
70089
|
-
key: `${key}_separator`
|
|
70090
|
-
});
|
|
70091
|
-
if (rowKept) {
|
|
70092
|
-
rowKept.separatorVnode = separatorVnode;
|
|
70093
|
-
}
|
|
70094
|
-
}
|
|
70095
|
-
pushRow(separatorVnode, item, rowIndex);
|
|
70096
|
-
}
|
|
70097
70186
|
pushRow(jsx(ListRowContext.Provider, {
|
|
70098
|
-
value:
|
|
70099
|
-
id: key,
|
|
70100
|
-
index: rowIndex,
|
|
70101
|
-
...getSkeletonRow()
|
|
70102
|
-
} : rowContextValue,
|
|
70187
|
+
value: rowContextValue,
|
|
70103
70188
|
children: rowVnode
|
|
70104
|
-
}, key), item, rowIndex);
|
|
70189
|
+
}, key), item, rowIndex, groupKey);
|
|
70105
70190
|
}
|
|
70106
70191
|
rowIndex++;
|
|
70107
70192
|
}
|
|
@@ -70115,6 +70200,35 @@ const ListItems = ({
|
|
|
70115
70200
|
return rows;
|
|
70116
70201
|
};
|
|
70117
70202
|
|
|
70203
|
+
// A run's row that has not arrived, standing where the real one will: it
|
|
70204
|
+
// mounts like any row (see createRunRows) and wears the separator of the gap
|
|
70205
|
+
// above it, the way a real row does in ListItemUI.
|
|
70206
|
+
const ListRunSkeletonRow = ({
|
|
70207
|
+
run,
|
|
70208
|
+
row,
|
|
70209
|
+
groupKey,
|
|
70210
|
+
separator,
|
|
70211
|
+
children
|
|
70212
|
+
}) => {
|
|
70213
|
+
const rowId = useId();
|
|
70214
|
+
run.mount(rowId, row.index, groupKey);
|
|
70215
|
+
useLayoutEffect(() => {
|
|
70216
|
+
return () => {
|
|
70217
|
+
run.unmount(rowId);
|
|
70218
|
+
};
|
|
70219
|
+
}, []);
|
|
70220
|
+
const rowVnode = jsx(ListRowContext.Provider, {
|
|
70221
|
+
value: row,
|
|
70222
|
+
children: children
|
|
70223
|
+
});
|
|
70224
|
+
if (!separator || run.isFirst(row.index, groupKey)) {
|
|
70225
|
+
return rowVnode;
|
|
70226
|
+
}
|
|
70227
|
+
return jsxs(Fragment, {
|
|
70228
|
+
children: [resolveSeparatorVnode(separator, row.index - 1), rowVnode]
|
|
70229
|
+
});
|
|
70230
|
+
};
|
|
70231
|
+
|
|
70118
70232
|
// What is drawn where rows were asked for and never came: the sentence and the
|
|
70119
70233
|
// way out, in the row itself — the rest of the list is fine, so replacing all
|
|
70120
70234
|
// of it (List's own `error`) would be a lie.
|