@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/dev/jsenv_navi.js
CHANGED
|
@@ -67329,10 +67329,11 @@ const ItemTransitionContext = createContext(false);
|
|
|
67329
67329
|
// that must reserve room for what is not rendered.
|
|
67330
67330
|
const ListVirtualContext = createContext(null);
|
|
67331
67331
|
// Set around each row a run of items renders (see ListItems): which row of the
|
|
67332
|
-
// collection it is,
|
|
67333
|
-
//
|
|
67334
|
-
//
|
|
67335
|
-
//
|
|
67332
|
+
// collection it is, where it stands among the rows the list holds, and the
|
|
67333
|
+
// run's own account of which rows mount (see createRunRows) — what the row
|
|
67334
|
+
// draws its separator from. Carried by context rather than injected into
|
|
67335
|
+
// whatever vnode renderItem returned, so that returning a component of one's
|
|
67336
|
+
// own — instead of a bare <List.Item> — works the same way.
|
|
67336
67337
|
const ListRowContext = createContext(null);
|
|
67337
67338
|
// The slot a child of the list stands in, by id (see ListDeclaredChildren). A
|
|
67338
67339
|
// row takes its place in the collection by slot: the place is then the list's
|
|
@@ -70161,22 +70162,12 @@ const ListItemRowResolver = props => {
|
|
|
70161
70162
|
...props
|
|
70162
70163
|
});
|
|
70163
70164
|
}
|
|
70164
|
-
// eslint-disable-next-line no-unused-vars
|
|
70165
|
-
const {
|
|
70166
|
-
id,
|
|
70167
|
-
index,
|
|
70168
|
-
item,
|
|
70169
|
-
rowMinHeight,
|
|
70170
|
-
rowMinWidth,
|
|
70171
|
-
...rowProps
|
|
70172
|
-
} = row;
|
|
70173
70165
|
return jsx(Next, {
|
|
70174
|
-
...rowProps,
|
|
70175
70166
|
...props,
|
|
70176
70167
|
id: props.id || row.id,
|
|
70177
70168
|
index: row.index,
|
|
70178
|
-
minHeight: props.minHeight === undefined ? rowMinHeight : props.minHeight,
|
|
70179
|
-
minWidth: props.minWidth === undefined ? rowMinWidth : props.minWidth
|
|
70169
|
+
minHeight: props.minHeight === undefined ? row.rowMinHeight : props.minHeight,
|
|
70170
|
+
minWidth: props.minWidth === undefined ? row.rowMinWidth : props.minWidth
|
|
70180
70171
|
});
|
|
70181
70172
|
};
|
|
70182
70173
|
const ListItemPresentationResolver = props => {
|
|
@@ -70254,8 +70245,8 @@ const ListItemUI = props => {
|
|
|
70254
70245
|
const virtual = useContext(ListVirtualContext);
|
|
70255
70246
|
const searchNoMatchMode = useContext(SearchNoMatchModeContext);
|
|
70256
70247
|
// The run this row belongs to, when it comes from one (see ListItems): it
|
|
70257
|
-
// registered the row
|
|
70258
|
-
//
|
|
70248
|
+
// registered the row and decided it is inside the render window. Whether
|
|
70249
|
+
// the row mounts is decided here, and told back to the run.
|
|
70259
70250
|
const row = useContext(ListRowContext);
|
|
70260
70251
|
const slotId = useContext(ListSlotContext);
|
|
70261
70252
|
// There is no standalone match/matchScore/highlight prop — participation
|
|
@@ -70287,16 +70278,24 @@ const ListItemUI = props => {
|
|
|
70287
70278
|
// name of this very component (idDefault, not the row's id): two components
|
|
70288
70279
|
// may stand for the same row for a moment, one leaving as the other arrives,
|
|
70289
70280
|
// and the one leaving must give back its own place, not the newcomer's.
|
|
70290
|
-
if (
|
|
70281
|
+
if (row) {
|
|
70291
70282
|
if (props.filtered) {
|
|
70292
|
-
|
|
70283
|
+
row.run.unmount(idDefault);
|
|
70293
70284
|
} else {
|
|
70294
|
-
|
|
70285
|
+
row.run.mount(idDefault, props.index, row.groupKey);
|
|
70295
70286
|
}
|
|
70287
|
+
} else if (props.filtered) {
|
|
70288
|
+
virtual.drop(idDefault);
|
|
70289
|
+
} else {
|
|
70290
|
+
props.index = virtual.take(idDefault, 1, slotId);
|
|
70296
70291
|
}
|
|
70297
70292
|
useLayoutEffect(() => {
|
|
70298
70293
|
return () => {
|
|
70299
|
-
|
|
70294
|
+
if (row) {
|
|
70295
|
+
row.run.unmount(idDefault);
|
|
70296
|
+
} else {
|
|
70297
|
+
virtual.drop(idDefault);
|
|
70298
|
+
}
|
|
70300
70299
|
};
|
|
70301
70300
|
}, []);
|
|
70302
70301
|
// Every row that is drawn registers itself, whether it was declared one by
|
|
@@ -70310,47 +70309,43 @@ const ListItemUI = props => {
|
|
|
70310
70309
|
if (props.filtered) {
|
|
70311
70310
|
return null;
|
|
70312
70311
|
}
|
|
70313
|
-
// html-hidden items: excluded from virtual scroll accounting but always in DOM
|
|
70314
|
-
if (props.hidden) {
|
|
70315
|
-
// Its separator stays too, and stays invisible with it: the point of
|
|
70316
|
-
// keeping a row that matches nothing is that nothing moves, and a divider
|
|
70317
|
-
// that leaves takes its own height away.
|
|
70318
|
-
if (!separator || props.index === 0) {
|
|
70319
|
-
return jsx(ListItemReal, {
|
|
70320
|
-
...props
|
|
70321
|
-
});
|
|
70322
|
-
}
|
|
70323
|
-
return jsxs(Fragment, {
|
|
70324
|
-
children: [cloneElement(resolveSeparatorVnode(separator, props.index - 1), {
|
|
70325
|
-
style: VISIBILITY_HIDDEN_STYLE
|
|
70326
|
-
}), jsx(ListItemReal, {
|
|
70327
|
-
...props
|
|
70328
|
-
})]
|
|
70329
|
-
});
|
|
70330
|
-
}
|
|
70331
|
-
if (row) {
|
|
70332
|
-
return jsx(ListItemReal, {
|
|
70333
|
-
...props
|
|
70334
|
-
});
|
|
70335
|
-
}
|
|
70336
|
-
const index = props.index;
|
|
70337
70312
|
const listItemVnode = jsx(ListItemReal, {
|
|
70338
70313
|
...props
|
|
70339
70314
|
});
|
|
70340
|
-
|
|
70341
|
-
// out (virtual.take above), not by the tracker's visibleIndex: during a
|
|
70342
|
-
// reorder render pass (items resorted by search score) the other items still
|
|
70343
|
-
// carry stale keyToExplicitOrder values, the binary search reads them, no
|
|
70344
|
-
// item comes out at 0 and a spurious separator appears at the top. Inside a
|
|
70345
|
-
// group, each group has its own tracker and its items do not reorder, so
|
|
70346
|
-
// groupVisibleIndex is reliable.
|
|
70347
|
-
const isFirstInList = groupVisibleIndex === null ? index === 0 : groupVisibleIndex === 0;
|
|
70348
|
-
if (!separator || isFirstInList) {
|
|
70315
|
+
if (!separator) {
|
|
70349
70316
|
return listItemVnode;
|
|
70350
70317
|
}
|
|
70351
|
-
//
|
|
70352
|
-
|
|
70353
|
-
|
|
70318
|
+
// The separator a row wears is the one at the gap above it, so the first row
|
|
70319
|
+
// that mounts wears none. "Am I first?" is answered by whoever handed out
|
|
70320
|
+
// the place — the run for its rows, the list's virtual for a declared one
|
|
70321
|
+
// (virtual.take above) — not by the tracker's visibleIndex: during a reorder
|
|
70322
|
+
// render pass (items resorted by search score) the other items still carry
|
|
70323
|
+
// stale keyToExplicitOrder values, the binary search reads them, no item
|
|
70324
|
+
// comes out at 0 and a spurious separator appears at the top. Inside a
|
|
70325
|
+
// declared group, each group has its own tracker and its items do not
|
|
70326
|
+
// reorder, so groupVisibleIndex is reliable there.
|
|
70327
|
+
let isFirst;
|
|
70328
|
+
if (row) {
|
|
70329
|
+
isFirst = row.run.isFirst(props.index, row.groupKey);
|
|
70330
|
+
} else if (groupVisibleIndex === null || props.hidden) {
|
|
70331
|
+
isFirst = props.index === 0;
|
|
70332
|
+
} else {
|
|
70333
|
+
isFirst = groupVisibleIndex === 0;
|
|
70334
|
+
}
|
|
70335
|
+
if (isFirst) {
|
|
70336
|
+
return listItemVnode;
|
|
70337
|
+
}
|
|
70338
|
+
// The gap index, only used as the function-form argument.
|
|
70339
|
+
const gapIndex = row || groupVisibleIndex === null || props.hidden ? props.index - 1 : groupVisibleIndex - 1;
|
|
70340
|
+
let separatorVnode = resolveSeparatorVnode(separator, gapIndex);
|
|
70341
|
+
if (props.hidden) {
|
|
70342
|
+
// A row kept in the DOM but hidden keeps its separator, hidden with it:
|
|
70343
|
+
// the point of keeping a row that matches nothing is that nothing moves,
|
|
70344
|
+
// and a divider that leaves takes its own height away.
|
|
70345
|
+
separatorVnode = cloneElement(separatorVnode, {
|
|
70346
|
+
style: VISIBILITY_HIDDEN_STYLE
|
|
70347
|
+
});
|
|
70348
|
+
}
|
|
70354
70349
|
return jsxs(Fragment, {
|
|
70355
70350
|
children: [separatorVnode, listItemVnode]
|
|
70356
70351
|
});
|
|
@@ -70972,6 +70967,101 @@ const sameSlotIds = (left, right) => {
|
|
|
70972
70967
|
return true;
|
|
70973
70968
|
};
|
|
70974
70969
|
|
|
70970
|
+
// Which of a run's rows mount, and which of them comes first. A run draws
|
|
70971
|
+
// every row of its window, and only the row itself knows, once it renders,
|
|
70972
|
+
// that it renders nothing (filtered out by a search, see ListItemUI). The
|
|
70973
|
+
// separator a row wears is the one at the gap above it, so the first row that
|
|
70974
|
+
// mounts wears none — and "first" is read off the rows that mount, not off
|
|
70975
|
+
// the collection. Rows say so as they render, in order, and the answer is a
|
|
70976
|
+
// signal: a row rendered from a kept vnode is rendered again when the row
|
|
70977
|
+
// before it leaves or comes back. Grouped rows are counted per group, the gap
|
|
70978
|
+
// above a group's first row being the group wrapper's own.
|
|
70979
|
+
const createRunRows = () => {
|
|
70980
|
+
// rowId → { index, groupKey }
|
|
70981
|
+
const rowById = new Map();
|
|
70982
|
+
// groupKey (undefined outside groups) → the index of the group's first
|
|
70983
|
+
// mounted row, -1 when none.
|
|
70984
|
+
const firstSignalByGroup = new Map();
|
|
70985
|
+
// Where the window starts: a run cut by the window has rows above its first
|
|
70986
|
+
// drawn one, and so does a run standing after declared rows.
|
|
70987
|
+
const windowFromSignal = signal(0);
|
|
70988
|
+
// Groups whose first row left: recounted on the next ask, or at the end of
|
|
70989
|
+
// the frame, whichever comes first.
|
|
70990
|
+
const staleGroupKeys = new Set();
|
|
70991
|
+
const firstSignalOf = groupKey => {
|
|
70992
|
+
let firstSignal = firstSignalByGroup.get(groupKey);
|
|
70993
|
+
if (!firstSignal) {
|
|
70994
|
+
firstSignal = signal(-1);
|
|
70995
|
+
firstSignalByGroup.set(groupKey, firstSignal);
|
|
70996
|
+
}
|
|
70997
|
+
return firstSignal;
|
|
70998
|
+
};
|
|
70999
|
+
const refresh = groupKey => {
|
|
71000
|
+
staleGroupKeys.delete(groupKey);
|
|
71001
|
+
let first = -1;
|
|
71002
|
+
for (const row of rowById.values()) {
|
|
71003
|
+
if (row.groupKey === groupKey && (first === -1 || row.index < first)) {
|
|
71004
|
+
first = row.index;
|
|
71005
|
+
}
|
|
71006
|
+
}
|
|
71007
|
+
firstSignalOf(groupKey).value = first;
|
|
71008
|
+
};
|
|
71009
|
+
const leave = row => {
|
|
71010
|
+
if (firstSignalOf(row.groupKey).peek() !== row.index) {
|
|
71011
|
+
return;
|
|
71012
|
+
}
|
|
71013
|
+
staleGroupKeys.add(row.groupKey);
|
|
71014
|
+
queueMicrotask(() => {
|
|
71015
|
+
if (staleGroupKeys.has(row.groupKey)) {
|
|
71016
|
+
refresh(row.groupKey);
|
|
71017
|
+
}
|
|
71018
|
+
});
|
|
71019
|
+
};
|
|
71020
|
+
return {
|
|
71021
|
+
setWindowFrom: windowFrom => {
|
|
71022
|
+
windowFromSignal.value = windowFrom;
|
|
71023
|
+
},
|
|
71024
|
+
mount: (rowId, index, groupKey) => {
|
|
71025
|
+
const row = rowById.get(rowId);
|
|
71026
|
+
if (row) {
|
|
71027
|
+
if (row.index === index && row.groupKey === groupKey) {
|
|
71028
|
+
return;
|
|
71029
|
+
}
|
|
71030
|
+
leave(row);
|
|
71031
|
+
row.index = index;
|
|
71032
|
+
row.groupKey = groupKey;
|
|
71033
|
+
} else {
|
|
71034
|
+
rowById.set(rowId, {
|
|
71035
|
+
index,
|
|
71036
|
+
groupKey
|
|
71037
|
+
});
|
|
71038
|
+
}
|
|
71039
|
+
const firstSignal = firstSignalOf(groupKey);
|
|
71040
|
+
const first = firstSignal.peek();
|
|
71041
|
+
if (first === -1 || index < first) {
|
|
71042
|
+
firstSignal.value = index;
|
|
71043
|
+
}
|
|
71044
|
+
},
|
|
71045
|
+
unmount: rowId => {
|
|
71046
|
+
const row = rowById.get(rowId);
|
|
71047
|
+
if (!row) {
|
|
71048
|
+
return;
|
|
71049
|
+
}
|
|
71050
|
+
rowById.delete(rowId);
|
|
71051
|
+
leave(row);
|
|
71052
|
+
},
|
|
71053
|
+
isFirst: (index, groupKey) => {
|
|
71054
|
+
if (staleGroupKeys.has(groupKey)) {
|
|
71055
|
+
refresh(groupKey);
|
|
71056
|
+
}
|
|
71057
|
+
if (firstSignalOf(groupKey).value !== index) {
|
|
71058
|
+
return false;
|
|
71059
|
+
}
|
|
71060
|
+
return groupKey !== undefined || windowFromSignal.value === 0;
|
|
71061
|
+
}
|
|
71062
|
+
};
|
|
71063
|
+
};
|
|
71064
|
+
|
|
70975
71065
|
// The walk that gives the list's children their places: a slot for each of
|
|
70976
71066
|
// them, declared to the list's virtual all at once before any child renders,
|
|
70977
71067
|
// and handed to the child through a provider of its own — which is what lets
|
|
@@ -71156,6 +71246,11 @@ const ListItems = ({
|
|
|
71156
71246
|
const slotId = useContext(ListSlotContext);
|
|
71157
71247
|
const renderWindow = useContext(RenderWindowContext);
|
|
71158
71248
|
const separator = useContext(SeparatorContext);
|
|
71249
|
+
const runRowsRef = useRef(null);
|
|
71250
|
+
if (!runRowsRef.current) {
|
|
71251
|
+
runRowsRef.current = createRunRows();
|
|
71252
|
+
}
|
|
71253
|
+
const runRows = runRowsRef.current;
|
|
71159
71254
|
// The vnode drawn for a row, kept by item: a run rendering again (its window
|
|
71160
71255
|
// moving, its first paint's budget giving way to the full one) hands preact
|
|
71161
71256
|
// the same vnode for a row that has not changed, and preact leaves that
|
|
@@ -71164,10 +71259,9 @@ const ListItems = ({
|
|
|
71164
71259
|
// row at the same index, in the same refreshing state: everything the
|
|
71165
71260
|
// function is given.
|
|
71166
71261
|
const rowVnodesRef = useRef(null);
|
|
71167
|
-
if (!rowVnodesRef.current || rowVnodesRef.current.renderItem !== renderItem
|
|
71262
|
+
if (!rowVnodesRef.current || rowVnodesRef.current.renderItem !== renderItem) {
|
|
71168
71263
|
rowVnodesRef.current = {
|
|
71169
71264
|
renderItem,
|
|
71170
|
-
separator,
|
|
71171
71265
|
byItem: new Map()
|
|
71172
71266
|
};
|
|
71173
71267
|
}
|
|
@@ -71216,6 +71310,7 @@ const ListItems = ({
|
|
|
71216
71310
|
const windowFrom = renderWindow.start > runStart ? renderWindow.start : runStart;
|
|
71217
71311
|
const windowTo = renderWindow.end < runEnd ? renderWindow.end : runEnd;
|
|
71218
71312
|
store.forget(rankOf(windowFrom), rankOf(windowTo));
|
|
71313
|
+
runRows.setWindowFrom(windowFrom);
|
|
71219
71314
|
|
|
71220
71315
|
// The row answers to its own id when the item carries one — that is what
|
|
71221
71316
|
// addresses it from outside (--navi-select, --navi-scroll, startAt) — and
|
|
@@ -71339,13 +71434,9 @@ const ListItems = ({
|
|
|
71339
71434
|
}, `${ownerId}_group_${group.key}`));
|
|
71340
71435
|
group = null;
|
|
71341
71436
|
};
|
|
71342
|
-
// Which group a row belongs to, or undefined when it belongs to none.
|
|
71343
|
-
// before the row is pushed as well as while pushing it: a row opening a
|
|
71344
|
-
// group is the one row that must not wear a separator (see below).
|
|
71437
|
+
// Which group a row belongs to, or undefined when it belongs to none.
|
|
71345
71438
|
const groupKeyOf = (item, rowIndex) => groupBy && item !== undefined ? groupBy(item, rowIndex) : undefined;
|
|
71346
|
-
const
|
|
71347
|
-
const pushRow = (rowNode, item, rowIndex) => {
|
|
71348
|
-
const groupKey = groupKeyOf(item, rowIndex);
|
|
71439
|
+
const pushRow = (rowNode, item, rowIndex, groupKey) => {
|
|
71349
71440
|
if (groupKey === undefined) {
|
|
71350
71441
|
closeGroup();
|
|
71351
71442
|
rows.push(rowNode);
|
|
@@ -71400,78 +71491,72 @@ const ListItems = ({
|
|
|
71400
71491
|
}
|
|
71401
71492
|
const item = getItemAt(rowIndex);
|
|
71402
71493
|
const key = item === undefined ? `${ownerId}_skeleton_${rowIndex}` : idOf(item, rowIndex);
|
|
71494
|
+
const groupKey = groupKeyOf(item, rowIndex);
|
|
71495
|
+
if (item === undefined) {
|
|
71496
|
+
// A row on its way never reaches ListItemUI (see ListItemSkeletonResolver):
|
|
71497
|
+
// it is stood among the rows that mount, and given its separator, here.
|
|
71498
|
+
let rowVnode;
|
|
71499
|
+
if (renderRowSkeleton === false) {
|
|
71500
|
+
// The row must still take its room: without it the rows below would
|
|
71501
|
+
// climb up and slide back down as the answer arrives.
|
|
71502
|
+
rowVnode = jsx(ListItem, {
|
|
71503
|
+
skeleton: true,
|
|
71504
|
+
style: VISIBILITY_HIDDEN_STYLE
|
|
71505
|
+
});
|
|
71506
|
+
} else if (renderRowSkeleton) {
|
|
71507
|
+
rowVnode = renderRowSkeleton(rowIndex);
|
|
71508
|
+
} else {
|
|
71509
|
+
rowVnode = jsx(ListItem, {
|
|
71510
|
+
skeleton: true
|
|
71511
|
+
});
|
|
71512
|
+
}
|
|
71513
|
+
if (rowVnode) {
|
|
71514
|
+
pushRow(jsx(ListRunSkeletonRow, {
|
|
71515
|
+
run: runRows,
|
|
71516
|
+
row: {
|
|
71517
|
+
id: key,
|
|
71518
|
+
index: rowIndex,
|
|
71519
|
+
...getSkeletonRow()
|
|
71520
|
+
},
|
|
71521
|
+
groupKey: groupKey,
|
|
71522
|
+
separator: separator,
|
|
71523
|
+
children: rowVnode
|
|
71524
|
+
}, key), item, rowIndex, groupKey);
|
|
71525
|
+
}
|
|
71526
|
+
rowIndex++;
|
|
71527
|
+
continue;
|
|
71528
|
+
}
|
|
71403
71529
|
let rowVnode;
|
|
71404
71530
|
let rowContextValue;
|
|
71405
|
-
|
|
71406
|
-
if (
|
|
71407
|
-
|
|
71408
|
-
|
|
71409
|
-
rowVnode = rowVnodeKept.vnode;
|
|
71410
|
-
rowContextValue = rowVnodeKept.rowContextValue;
|
|
71411
|
-
rowKept = rowVnodeKept;
|
|
71412
|
-
} else {
|
|
71413
|
-
rowVnode = renderItem(item, rowIndex, renderItemState);
|
|
71414
|
-
// Kept with the vnode, for the same reason: a context value that is a
|
|
71415
|
-
// fresh object on every render forces every consumer of it to render,
|
|
71416
|
-
// which is the row's own chain — the vnode handed back unchanged would
|
|
71417
|
-
// then buy nothing.
|
|
71418
|
-
rowContextValue = {
|
|
71419
|
-
id: key,
|
|
71420
|
-
index: rowIndex,
|
|
71421
|
-
item
|
|
71422
|
-
};
|
|
71423
|
-
rowKept = {
|
|
71424
|
-
vnode: rowVnode,
|
|
71425
|
-
rowContextValue,
|
|
71426
|
-
rowIndex,
|
|
71427
|
-
refreshing: renderItemState.refreshing,
|
|
71428
|
-
separatorVnode: null
|
|
71429
|
-
};
|
|
71430
|
-
rowVnodesByItem.set(item, rowKept);
|
|
71431
|
-
}
|
|
71432
|
-
} else if (renderRowSkeleton === false) {
|
|
71433
|
-
// The row must still take its room: without it the rows below would
|
|
71434
|
-
// climb up and slide back down as the answer arrives.
|
|
71435
|
-
rowVnode = jsx(ListItem, {
|
|
71436
|
-
skeleton: true,
|
|
71437
|
-
style: VISIBILITY_HIDDEN_STYLE
|
|
71438
|
-
});
|
|
71439
|
-
} else if (renderRowSkeleton) {
|
|
71440
|
-
rowVnode = renderRowSkeleton(rowIndex);
|
|
71531
|
+
const rowVnodeKept = rowVnodesByItem.get(item);
|
|
71532
|
+
if (rowVnodeKept && rowVnodeKept.rowIndex === rowIndex && rowVnodeKept.refreshing === renderItemState.refreshing && rowVnodeKept.rowContextValue.groupKey === groupKey) {
|
|
71533
|
+
rowVnode = rowVnodeKept.vnode;
|
|
71534
|
+
rowContextValue = rowVnodeKept.rowContextValue;
|
|
71441
71535
|
} else {
|
|
71442
|
-
rowVnode =
|
|
71443
|
-
|
|
71536
|
+
rowVnode = renderItem(item, rowIndex, renderItemState);
|
|
71537
|
+
// Kept with the vnode, for the same reason: a context value that is a
|
|
71538
|
+
// fresh object on every render forces every consumer of it to render,
|
|
71539
|
+
// which is the row's own chain — the vnode handed back unchanged would
|
|
71540
|
+
// then buy nothing.
|
|
71541
|
+
rowContextValue = {
|
|
71542
|
+
id: key,
|
|
71543
|
+
index: rowIndex,
|
|
71544
|
+
item,
|
|
71545
|
+
run: runRows,
|
|
71546
|
+
groupKey
|
|
71547
|
+
};
|
|
71548
|
+
rowVnodesByItem.set(item, {
|
|
71549
|
+
vnode: rowVnode,
|
|
71550
|
+
rowContextValue,
|
|
71551
|
+
rowIndex,
|
|
71552
|
+
refreshing: renderItemState.refreshing
|
|
71444
71553
|
});
|
|
71445
71554
|
}
|
|
71446
71555
|
if (rowVnode) {
|
|
71447
|
-
// The first row of a group wears no separator: the gap it sits at is the
|
|
71448
|
-
// one between two groups, and that gap is the group wrapper's own — it
|
|
71449
|
-
// is a row of the list like any other and draws its separator itself
|
|
71450
|
-
// (see ListItemUI). Drawn here it would land inside the group instead,
|
|
71451
|
-
// as a hairline under the label.
|
|
71452
|
-
const drawSeparator = separator && rowIndex > 0 && !opensGroup(groupKeyOf(item, rowIndex));
|
|
71453
|
-
if (drawSeparator) {
|
|
71454
|
-
// Kept with the row too: a separator built again is a separator
|
|
71455
|
-
// rendered again.
|
|
71456
|
-
let separatorVnode = rowKept ? rowKept.separatorVnode : null;
|
|
71457
|
-
if (!separatorVnode) {
|
|
71458
|
-
separatorVnode = cloneElement(resolveSeparatorVnode(separator, rowIndex - 1), {
|
|
71459
|
-
key: `${key}_separator`
|
|
71460
|
-
});
|
|
71461
|
-
if (rowKept) {
|
|
71462
|
-
rowKept.separatorVnode = separatorVnode;
|
|
71463
|
-
}
|
|
71464
|
-
}
|
|
71465
|
-
pushRow(separatorVnode, item, rowIndex);
|
|
71466
|
-
}
|
|
71467
71556
|
pushRow(jsx(ListRowContext.Provider, {
|
|
71468
|
-
value:
|
|
71469
|
-
id: key,
|
|
71470
|
-
index: rowIndex,
|
|
71471
|
-
...getSkeletonRow()
|
|
71472
|
-
} : rowContextValue,
|
|
71557
|
+
value: rowContextValue,
|
|
71473
71558
|
children: rowVnode
|
|
71474
|
-
}, key), item, rowIndex);
|
|
71559
|
+
}, key), item, rowIndex, groupKey);
|
|
71475
71560
|
}
|
|
71476
71561
|
rowIndex++;
|
|
71477
71562
|
}
|
|
@@ -71485,6 +71570,35 @@ const ListItems = ({
|
|
|
71485
71570
|
return rows;
|
|
71486
71571
|
};
|
|
71487
71572
|
|
|
71573
|
+
// A run's row that has not arrived, standing where the real one will: it
|
|
71574
|
+
// mounts like any row (see createRunRows) and wears the separator of the gap
|
|
71575
|
+
// above it, the way a real row does in ListItemUI.
|
|
71576
|
+
const ListRunSkeletonRow = ({
|
|
71577
|
+
run,
|
|
71578
|
+
row,
|
|
71579
|
+
groupKey,
|
|
71580
|
+
separator,
|
|
71581
|
+
children
|
|
71582
|
+
}) => {
|
|
71583
|
+
const rowId = useId();
|
|
71584
|
+
run.mount(rowId, row.index, groupKey);
|
|
71585
|
+
useLayoutEffect(() => {
|
|
71586
|
+
return () => {
|
|
71587
|
+
run.unmount(rowId);
|
|
71588
|
+
};
|
|
71589
|
+
}, []);
|
|
71590
|
+
const rowVnode = jsx(ListRowContext.Provider, {
|
|
71591
|
+
value: row,
|
|
71592
|
+
children: children
|
|
71593
|
+
});
|
|
71594
|
+
if (!separator || run.isFirst(row.index, groupKey)) {
|
|
71595
|
+
return rowVnode;
|
|
71596
|
+
}
|
|
71597
|
+
return jsxs(Fragment, {
|
|
71598
|
+
children: [resolveSeparatorVnode(separator, row.index - 1), rowVnode]
|
|
71599
|
+
});
|
|
71600
|
+
};
|
|
71601
|
+
|
|
71488
71602
|
// What is drawn where rows were asked for and never came: the sentence and the
|
|
71489
71603
|
// way out, in the row itself — the rest of the list is fine, so replacing all
|
|
71490
71604
|
// of it (List's own `error`) would be a lie.
|