@jsenv/navi 0.29.138 → 0.29.141
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/jsenv_navi.js +350 -54
- package/dist/jsenv_navi.js.map +36 -12
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -33367,6 +33367,34 @@ const isNamelessGrouping = (child, uiState) =>
|
|
|
33367
33367
|
typeof uiState === "object" &&
|
|
33368
33368
|
!Array.isArray(uiState);
|
|
33369
33369
|
|
|
33370
|
+
// Is this value the empty the child writes when it holds nothing? Reading it
|
|
33371
|
+
// back out of the object means the child holds nothing — which is `undefined`,
|
|
33372
|
+
// not the empty itself (see the object group's distributeChildUIState below).
|
|
33373
|
+
const uiStateIsChildEmpty = (uiState, child) => {
|
|
33374
|
+
const { emptyUIState } = child;
|
|
33375
|
+
if (emptyUIState === undefined) {
|
|
33376
|
+
return false;
|
|
33377
|
+
}
|
|
33378
|
+
if (uiState === emptyUIState) {
|
|
33379
|
+
return true;
|
|
33380
|
+
}
|
|
33381
|
+
// The empties are shapes, not identities: what comes back down went through
|
|
33382
|
+
// a restore, a signal or an action and is a different array/object than the
|
|
33383
|
+
// EMPTY_ARRAY/EMPTY_OBJECT that went up.
|
|
33384
|
+
if (Array.isArray(emptyUIState)) {
|
|
33385
|
+
return Array.isArray(uiState) && uiState.length === 0;
|
|
33386
|
+
}
|
|
33387
|
+
if (typeof emptyUIState === "object" && emptyUIState !== null) {
|
|
33388
|
+
return (
|
|
33389
|
+
uiState !== null &&
|
|
33390
|
+
typeof uiState === "object" &&
|
|
33391
|
+
!Array.isArray(uiState) &&
|
|
33392
|
+
Object.keys(uiState).length === 0
|
|
33393
|
+
);
|
|
33394
|
+
}
|
|
33395
|
+
return false;
|
|
33396
|
+
};
|
|
33397
|
+
|
|
33370
33398
|
const firstDefinedChildUIState = (children) => {
|
|
33371
33399
|
for (const child of children) {
|
|
33372
33400
|
const childUIState = child.uiState;
|
|
@@ -33504,7 +33532,19 @@ const GROUP_DEFAULTS = {
|
|
|
33504
33532
|
typeof newUIState === "object" &&
|
|
33505
33533
|
Object.prototype.hasOwnProperty.call(newUIState, childName)
|
|
33506
33534
|
) {
|
|
33507
|
-
|
|
33535
|
+
const childUIState = newUIState[childName];
|
|
33536
|
+
// The exact inverse of the empty aggregateChildStates wrote just
|
|
33537
|
+
// above: what a child holding nothing put into the object
|
|
33538
|
+
// must come back out as nothing. Handed back as-is it reads as a value
|
|
33539
|
+
// — a checkbox takes any state that is not `undefined` as checked,
|
|
33540
|
+
// `false` included (see the `checked` line in control_hooks'
|
|
33541
|
+
// toDomProps) — so restoring the object (a picker cancelling on Escape)
|
|
33542
|
+
// would check every box it contains, and the group would then re-derive
|
|
33543
|
+
// the `true` nobody said.
|
|
33544
|
+
if (uiStateIsChildEmpty(childUIState, child)) {
|
|
33545
|
+
return undefined;
|
|
33546
|
+
}
|
|
33547
|
+
return childUIState;
|
|
33508
33548
|
}
|
|
33509
33549
|
// Merged in on the way up (see above), so on the way down it takes the
|
|
33510
33550
|
// whole object and picks out its own keys — the same value it produced.
|
|
@@ -33732,6 +33772,15 @@ const useUIGroupStateController = (
|
|
|
33732
33772
|
// wheels nobody turned have settled nothing. Only the default shapes
|
|
33733
33773
|
// fall back to the empty of their type, where "no child says anything"
|
|
33734
33774
|
// and "the value is empty" are the same sentence.
|
|
33775
|
+
//
|
|
33776
|
+
// Not `fallbackState !== undefined`, tempting as it looks: `stateType`
|
|
33777
|
+
// is what the group's OWN shape would be, and a caller-supplied
|
|
33778
|
+
// aggregate is free to hold another one — TimeSpin and WheelTime are
|
|
33779
|
+
// "HH:MM" strings inside groups declared `stateType: "object"`, and
|
|
33780
|
+
// handing them `{}` for "unanswered" would empty a signal holding a
|
|
33781
|
+
// time. An aggregate that does want the empty of the declared type
|
|
33782
|
+
// takes it: it is handed `fallbackState` as its second argument (see
|
|
33783
|
+
// ListSelectable, which returns it for an emptied multiple list).
|
|
33735
33784
|
return stateShapeIsTheDefaultOne ? fallbackState : undefined;
|
|
33736
33785
|
};
|
|
33737
33786
|
|
|
@@ -61306,7 +61355,13 @@ const ListSelectable = props => {
|
|
|
61306
61355
|
if (selectionRef.current === undefined) {
|
|
61307
61356
|
selectionRef.current = Object.hasOwn(props, "value") ? props.value : props.defaultValue;
|
|
61308
61357
|
}
|
|
61309
|
-
|
|
61358
|
+
// `fallbackState` is the empty of the shape the list declared below
|
|
61359
|
+
// (`stateType`): `[]` for a multiple list, nothing for a single one. Taking
|
|
61360
|
+
// it is what lets an emptied list say "empty" — `undefined` is the word for
|
|
61361
|
+
// "unset", and a bound stateSignal reads that as "nothing decided here, go
|
|
61362
|
+
// back to the default" (see docs/control_value.md), which is how a list
|
|
61363
|
+
// emptied down to its last row puts that row back on reload.
|
|
61364
|
+
const aggregateChildStates = (children, fallbackState) => {
|
|
61310
61365
|
const kept = selectionRef.current;
|
|
61311
61366
|
if (multiple) {
|
|
61312
61367
|
const drawnValues = new Set(children.map(child => child.props.value));
|
|
@@ -61316,7 +61371,7 @@ const ListSelectable = props => {
|
|
|
61316
61371
|
stillSelected.push(child.uiState);
|
|
61317
61372
|
}
|
|
61318
61373
|
}
|
|
61319
|
-
const values = stillSelected.length === 0 ?
|
|
61374
|
+
const values = stillSelected.length === 0 ? fallbackState : stillSelected;
|
|
61320
61375
|
selectionRef.current = values;
|
|
61321
61376
|
return values;
|
|
61322
61377
|
}
|
|
@@ -61929,6 +61984,10 @@ const ListVirtualContext = createContext(null);
|
|
|
61929
61984
|
// that returning a component of one's own — instead of a bare <List.Item> —
|
|
61930
61985
|
// works the same way.
|
|
61931
61986
|
const ListRowContext = createContext(null);
|
|
61987
|
+
// The slot a child of the list stands in, by id (see ListDeclaredChildren). A
|
|
61988
|
+
// row takes its place in the collection by slot: the place is then the list's
|
|
61989
|
+
// to move, and the row's to follow — see createListVirtual.
|
|
61990
|
+
const ListSlotContext = createContext(null);
|
|
61932
61991
|
const css$x = /* css */`
|
|
61933
61992
|
@layer navi {
|
|
61934
61993
|
.navi_list_container {
|
|
@@ -62932,24 +62991,11 @@ const ListFirstResolver = props => {
|
|
|
62932
62991
|
props.ref = props.ref || refDefault;
|
|
62933
62992
|
const idDefault = useId();
|
|
62934
62993
|
props.id = props.id || idDefault;
|
|
62935
|
-
// A new pass every time the caller walks the children: they are about to
|
|
62936
|
-
// say again, in order, which rows of the collection they stand for. Decided
|
|
62937
|
-
// here, on the children as the caller gave them. Further down the chain a
|
|
62938
|
-
// resolver re-rendering on its own hands the rows down inside a vnode of its
|
|
62939
|
-
// own (ListSelectable wraps them in the group's contexts) — but the rows are
|
|
62940
|
-
// the very vnodes preact already holds, and it skips them: nothing is said
|
|
62941
|
-
// again, so nothing may be asked again either (see createListVirtual).
|
|
62942
62994
|
const virtualRef = useRef(null);
|
|
62943
62995
|
if (!virtualRef.current) {
|
|
62944
62996
|
virtualRef.current = createListVirtual();
|
|
62945
62997
|
}
|
|
62946
|
-
|
|
62947
|
-
const childrenPreviousRef = useRef(undefined);
|
|
62948
|
-
if (childrenPreviousRef.current !== props.children) {
|
|
62949
|
-
childrenPreviousRef.current = props.children;
|
|
62950
|
-
virtual.openPass();
|
|
62951
|
-
}
|
|
62952
|
-
props.virtual = virtual;
|
|
62998
|
+
props.virtual = virtualRef.current;
|
|
62953
62999
|
return jsx(Next, {
|
|
62954
63000
|
...props
|
|
62955
63001
|
});
|
|
@@ -64685,7 +64731,9 @@ const UnorderedList = ({
|
|
|
64685
64731
|
value: null,
|
|
64686
64732
|
children: jsx(ListColumnsContext.Provider, {
|
|
64687
64733
|
value: columns || null,
|
|
64688
|
-
children:
|
|
64734
|
+
children: jsx(ListDeclaredChildren, {
|
|
64735
|
+
children: children
|
|
64736
|
+
})
|
|
64689
64737
|
})
|
|
64690
64738
|
})
|
|
64691
64739
|
})
|
|
@@ -64896,6 +64944,7 @@ const ListItemUI = props => {
|
|
|
64896
64944
|
// registered the row, decided it is inside the render window, and placed its
|
|
64897
64945
|
// separator. All that is left here is to draw it.
|
|
64898
64946
|
const row = useContext(ListRowContext);
|
|
64947
|
+
const slotId = useContext(ListSlotContext);
|
|
64899
64948
|
// There is no standalone match/matchScore/highlight prop — participation
|
|
64900
64949
|
// in a matching system (search, filter…) only goes through `matchInfo`
|
|
64901
64950
|
// (e.g. useSearchText's getItemMatchInfo(item): { match, matchScore,
|
|
@@ -64919,12 +64968,24 @@ const ListItemUI = props => {
|
|
|
64919
64968
|
}
|
|
64920
64969
|
}
|
|
64921
64970
|
// Where a row sits is where it was declared, full stop: a list is written in
|
|
64922
|
-
// the order it reads.
|
|
64923
|
-
//
|
|
64924
|
-
// already knows its place; the run gave it.
|
|
64925
|
-
|
|
64926
|
-
|
|
64971
|
+
// the order it reads. Its slot is what says that — a search that reorders
|
|
64972
|
+
// rows reorders the rows it declares, and the slots follow. A row drawn by a
|
|
64973
|
+
// run already knows its place; the run gave it. The place is taken in the
|
|
64974
|
+
// name of this very component (idDefault, not the row's id): two components
|
|
64975
|
+
// may stand for the same row for a moment, one leaving as the other arrives,
|
|
64976
|
+
// and the one leaving must give back its own place, not the newcomer's.
|
|
64977
|
+
if (!row) {
|
|
64978
|
+
if (props.filtered) {
|
|
64979
|
+
virtual.drop(idDefault);
|
|
64980
|
+
} else {
|
|
64981
|
+
props.index = virtual.take(idDefault, 1, slotId);
|
|
64982
|
+
}
|
|
64927
64983
|
}
|
|
64984
|
+
useLayoutEffect(() => {
|
|
64985
|
+
return () => {
|
|
64986
|
+
virtual.drop(idDefault);
|
|
64987
|
+
};
|
|
64988
|
+
}, []);
|
|
64928
64989
|
// Every row that is drawn registers itself, whether it was declared one by
|
|
64929
64990
|
// one or drawn by a run: what it says about itself (its value, whether it is
|
|
64930
64991
|
// selected) is written where it is drawn, in one place.
|
|
@@ -65281,12 +65342,20 @@ List.Item = ListItem;
|
|
|
65281
65342
|
// where each child's rows start.
|
|
65282
65343
|
//
|
|
65283
65344
|
// A child knows how many rows it stands for but not what was declared before
|
|
65284
|
-
// it,
|
|
65285
|
-
//
|
|
65286
|
-
//
|
|
65287
|
-
//
|
|
65288
|
-
//
|
|
65289
|
-
//
|
|
65345
|
+
// it, and it cannot deduce that from when it renders: a render is free to skip
|
|
65346
|
+
// it. A child that draws from signals and whose props are all referentially
|
|
65347
|
+
// === the previous ones does not render again (@preact/signals installs a
|
|
65348
|
+
// shouldComponentUpdate that says so), which is what any child nobody rebuilt
|
|
65349
|
+
// this frame is — and children numbered as they render would then slide up
|
|
65350
|
+
// into the place of the one that was skipped.
|
|
65351
|
+
//
|
|
65352
|
+
// So the places are read off the walk instead of off the renders: the list
|
|
65353
|
+
// names a slot for each of its children and declares them here, in order,
|
|
65354
|
+
// before any of them renders (see ListDeclaredChildren). A child then takes
|
|
65355
|
+
// its place BY SLOT, and the place is a signal: it moves when what stands
|
|
65356
|
+
// before it changes — a row filtered out, a run taking in rows, a slot added
|
|
65357
|
+
// or moved — and the child follows, rendered again for it whether or not
|
|
65358
|
+
// anything else would have rendered it.
|
|
65290
65359
|
const createListVirtual = () => {
|
|
65291
65360
|
const totalSignal = signal(0);
|
|
65292
65361
|
// Bumped whenever a run takes in rows. The list itself has to hear about it:
|
|
@@ -65298,10 +65367,109 @@ const createListVirtual = () => {
|
|
|
65298
65367
|
// an attribute: what is drawn is from before, and the app may want to say so
|
|
65299
65368
|
// without taking anything away.
|
|
65300
65369
|
const refreshingSignal = signal(0);
|
|
65301
|
-
|
|
65370
|
+
// The slots each walk declared, in order, by the slot the walk stands in
|
|
65371
|
+
// (null for the list's own children). Together they are a tree: a group's
|
|
65372
|
+
// rows live inside the group's slot.
|
|
65373
|
+
const slotIdsByParent = new Map();
|
|
65374
|
+
// Who took a place — a row, or a run of rows — and how many rows of the
|
|
65375
|
+
// collection it stands for. The place itself is a signal, see take.
|
|
65376
|
+
const ownerById = new Map();
|
|
65377
|
+
// The owners standing in each slot, in the order they took their place.
|
|
65378
|
+
// One, as a rule; a child that renders several rows keeps them in the order
|
|
65379
|
+
// they first rendered, which is all it can be told.
|
|
65380
|
+
const ownerIdsBySlot = new Map();
|
|
65302
65381
|
const locatorByOwner = new Map();
|
|
65303
|
-
|
|
65304
|
-
|
|
65382
|
+
// The slots as the tree reads, first to last, and where each stands in it.
|
|
65383
|
+
// Rebuilt once a walk has changed the tree, read to place the owners.
|
|
65384
|
+
const slotWalk = [];
|
|
65385
|
+
const rankBySlot = new Map();
|
|
65386
|
+
let rowTotal = 0;
|
|
65387
|
+
// Owners have left and the others have not been moved up yet. Done on the
|
|
65388
|
+
// next ask rather than on the spot: rows leave many at a time (a search, a
|
|
65389
|
+
// list unmounting), and moving the others up once is enough.
|
|
65390
|
+
let placesStale = false;
|
|
65391
|
+
// Where the last slot holding an owner stands: an owner arriving at or after
|
|
65392
|
+
// it is placed at the end without going over the others — a whole first
|
|
65393
|
+
// render, rows arriving in order, costs each row nothing but itself.
|
|
65394
|
+
let rankOwnedLast = -1;
|
|
65395
|
+
const rebuildWalk = () => {
|
|
65396
|
+
slotWalk.length = 0;
|
|
65397
|
+
rankBySlot.clear();
|
|
65398
|
+
const visit = parentSlotId => {
|
|
65399
|
+
const slotIds = slotIdsByParent.get(parentSlotId);
|
|
65400
|
+
if (!slotIds) {
|
|
65401
|
+
return;
|
|
65402
|
+
}
|
|
65403
|
+
for (const slotId of slotIds) {
|
|
65404
|
+
rankBySlot.set(slotId, slotWalk.length);
|
|
65405
|
+
slotWalk.push(slotId);
|
|
65406
|
+
visit(slotId);
|
|
65407
|
+
}
|
|
65408
|
+
};
|
|
65409
|
+
visit(null);
|
|
65410
|
+
};
|
|
65411
|
+
// Every place, in one go: a place is the sum of what stands before it, so
|
|
65412
|
+
// there is nothing to hand out one at a time. Writing a place that did not
|
|
65413
|
+
// change wakes nobody — a signal ignores a value equal to its own.
|
|
65414
|
+
const refreshPlaces = () => {
|
|
65415
|
+
placesStale = false;
|
|
65416
|
+
let index = 0;
|
|
65417
|
+
let rank = 0;
|
|
65418
|
+
rankOwnedLast = -1;
|
|
65419
|
+
while (rank < slotWalk.length) {
|
|
65420
|
+
const ownerIds = ownerIdsBySlot.get(slotWalk[rank]);
|
|
65421
|
+
if (ownerIds) {
|
|
65422
|
+
for (const ownerId of ownerIds) {
|
|
65423
|
+
const owner = ownerById.get(ownerId);
|
|
65424
|
+
owner.placeSignal.value = index;
|
|
65425
|
+
index += owner.rowCount;
|
|
65426
|
+
}
|
|
65427
|
+
rankOwnedLast = rank;
|
|
65428
|
+
}
|
|
65429
|
+
rank++;
|
|
65430
|
+
}
|
|
65431
|
+
rowTotal = index;
|
|
65432
|
+
totalSignal.value = index;
|
|
65433
|
+
};
|
|
65434
|
+
const addToSlot = (slotId, ownerId) => {
|
|
65435
|
+
const ownerIds = ownerIdsBySlot.get(slotId);
|
|
65436
|
+
if (ownerIds) {
|
|
65437
|
+
ownerIds.push(ownerId);
|
|
65438
|
+
} else {
|
|
65439
|
+
ownerIdsBySlot.set(slotId, [ownerId]);
|
|
65440
|
+
}
|
|
65441
|
+
};
|
|
65442
|
+
const removeFromSlot = (slotId, ownerId) => {
|
|
65443
|
+
const ownerIds = ownerIdsBySlot.get(slotId);
|
|
65444
|
+
if (!ownerIds) {
|
|
65445
|
+
return;
|
|
65446
|
+
}
|
|
65447
|
+
const index = ownerIds.indexOf(ownerId);
|
|
65448
|
+
if (index !== -1) {
|
|
65449
|
+
ownerIds.splice(index, 1);
|
|
65450
|
+
}
|
|
65451
|
+
if (ownerIds.length === 0) {
|
|
65452
|
+
ownerIdsBySlot.delete(slotId);
|
|
65453
|
+
}
|
|
65454
|
+
};
|
|
65455
|
+
// A slot the walk no longer names: whatever stood in it is gone, and so is
|
|
65456
|
+
// whatever a walk inside it had declared.
|
|
65457
|
+
const dropSlot = slotId => {
|
|
65458
|
+
const ownerIds = ownerIdsBySlot.get(slotId);
|
|
65459
|
+
if (ownerIds) {
|
|
65460
|
+
for (const ownerId of ownerIds) {
|
|
65461
|
+
ownerById.delete(ownerId);
|
|
65462
|
+
}
|
|
65463
|
+
ownerIdsBySlot.delete(slotId);
|
|
65464
|
+
}
|
|
65465
|
+
const childSlotIds = slotIdsByParent.get(slotId);
|
|
65466
|
+
if (childSlotIds) {
|
|
65467
|
+
slotIdsByParent.delete(slotId);
|
|
65468
|
+
for (const childSlotId of childSlotIds) {
|
|
65469
|
+
dropSlot(childSlotId);
|
|
65470
|
+
}
|
|
65471
|
+
}
|
|
65472
|
+
};
|
|
65305
65473
|
const virtual = {
|
|
65306
65474
|
totalSignal,
|
|
65307
65475
|
pagesSignal,
|
|
@@ -65322,15 +65490,32 @@ const createListVirtual = () => {
|
|
|
65322
65490
|
horizontal: false,
|
|
65323
65491
|
virtualItemSizeSignal: null,
|
|
65324
65492
|
renderSkeleton: undefined,
|
|
65325
|
-
//
|
|
65326
|
-
//
|
|
65327
|
-
//
|
|
65328
|
-
//
|
|
65329
|
-
//
|
|
65330
|
-
|
|
65331
|
-
|
|
65332
|
-
|
|
65493
|
+
// The children a walk stands over, in order — said in one call, before any
|
|
65494
|
+
// of them renders, so that what a child asks next is answered against the
|
|
65495
|
+
// whole picture and not against the children that happened to render
|
|
65496
|
+
// first. Said again on every render of the walk, and heard only when
|
|
65497
|
+
// something moved.
|
|
65498
|
+
declareSlots: (parentSlotId, slotIds) => {
|
|
65499
|
+
const slotIdsPrevious = slotIdsByParent.get(parentSlotId);
|
|
65500
|
+
if (slotIdsPrevious && sameSlotIds(slotIdsPrevious, slotIds)) {
|
|
65501
|
+
return;
|
|
65502
|
+
}
|
|
65503
|
+
if (slotIdsPrevious) {
|
|
65504
|
+
const slotIdSet = new Set(slotIds);
|
|
65505
|
+
for (const slotId of slotIdsPrevious) {
|
|
65506
|
+
if (!slotIdSet.has(slotId)) {
|
|
65507
|
+
dropSlot(slotId);
|
|
65508
|
+
}
|
|
65509
|
+
}
|
|
65510
|
+
}
|
|
65511
|
+
slotIdsByParent.set(parentSlotId, slotIds);
|
|
65512
|
+
rebuildWalk();
|
|
65513
|
+
refreshPlaces();
|
|
65333
65514
|
},
|
|
65515
|
+
// Whether something has taken this slot for its own: what it renders
|
|
65516
|
+
// inside is then its to place (a run draws its groups with their rows
|
|
65517
|
+
// already placed), and no walk inside it has anything to declare.
|
|
65518
|
+
slotHasOwner: slotId => ownerIdsBySlot.has(slotId),
|
|
65334
65519
|
// Whether any run of rows lives in this list: what makes a render window
|
|
65335
65520
|
// mean anything (see List's renderBudget).
|
|
65336
65521
|
hasRuns: () => locatorByOwner.size > 0,
|
|
@@ -65350,23 +65535,130 @@ const createListVirtual = () => {
|
|
|
65350
65535
|
}
|
|
65351
65536
|
return null;
|
|
65352
65537
|
},
|
|
65353
|
-
|
|
65354
|
-
|
|
65355
|
-
|
|
65356
|
-
|
|
65357
|
-
|
|
65358
|
-
|
|
65359
|
-
|
|
65360
|
-
|
|
65361
|
-
|
|
65538
|
+
// The place the owner's rows start at — read from a signal, so that the
|
|
65539
|
+
// owner is rendered again when it moves (see createListVirtual). Asked on
|
|
65540
|
+
// every render, and answered without a second look for as long as the
|
|
65541
|
+
// owner stands in the same slot for the same number of rows.
|
|
65542
|
+
take: (ownerId, rowCount, slotId) => {
|
|
65543
|
+
let owner = ownerById.get(ownerId);
|
|
65544
|
+
if (owner) {
|
|
65545
|
+
if (owner.slotId !== slotId || owner.rowCount !== rowCount) {
|
|
65546
|
+
removeFromSlot(owner.slotId, ownerId);
|
|
65547
|
+
addToSlot(slotId, ownerId);
|
|
65548
|
+
owner.slotId = slotId;
|
|
65549
|
+
owner.rowCount = rowCount;
|
|
65550
|
+
placesStale = true;
|
|
65551
|
+
}
|
|
65552
|
+
if (placesStale) {
|
|
65553
|
+
refreshPlaces();
|
|
65554
|
+
}
|
|
65555
|
+
return owner.placeSignal.value;
|
|
65556
|
+
}
|
|
65557
|
+
if (placesStale) {
|
|
65558
|
+
refreshPlaces();
|
|
65559
|
+
}
|
|
65560
|
+
const rank = rankBySlot.get(slotId);
|
|
65561
|
+
addToSlot(slotId, ownerId);
|
|
65562
|
+
if (rank !== undefined && rank >= rankOwnedLast) {
|
|
65563
|
+
owner = {
|
|
65564
|
+
slotId,
|
|
65565
|
+
rowCount,
|
|
65566
|
+
placeSignal: signal(rowTotal)
|
|
65567
|
+
};
|
|
65568
|
+
ownerById.set(ownerId, owner);
|
|
65569
|
+
rowTotal += rowCount;
|
|
65570
|
+
rankOwnedLast = rank;
|
|
65571
|
+
totalSignal.value = rowTotal;
|
|
65572
|
+
return owner.placeSignal.value;
|
|
65573
|
+
}
|
|
65574
|
+
owner = {
|
|
65575
|
+
slotId,
|
|
65576
|
+
rowCount,
|
|
65577
|
+
placeSignal: signal(0)
|
|
65578
|
+
};
|
|
65579
|
+
ownerById.set(ownerId, owner);
|
|
65580
|
+
refreshPlaces();
|
|
65581
|
+
return owner.placeSignal.value;
|
|
65582
|
+
},
|
|
65583
|
+
// The owner stands for no row of the collection: it was filtered out by a
|
|
65584
|
+
// search, or it is gone.
|
|
65585
|
+
drop: ownerId => {
|
|
65586
|
+
const owner = ownerById.get(ownerId);
|
|
65587
|
+
if (!owner) {
|
|
65588
|
+
return;
|
|
65589
|
+
}
|
|
65590
|
+
ownerById.delete(ownerId);
|
|
65591
|
+
removeFromSlot(owner.slotId, ownerId);
|
|
65592
|
+
if (placesStale) {
|
|
65593
|
+
return;
|
|
65594
|
+
}
|
|
65595
|
+
placesStale = true;
|
|
65596
|
+
queueMicrotask(() => {
|
|
65597
|
+
if (placesStale) {
|
|
65598
|
+
refreshPlaces();
|
|
65599
|
+
}
|
|
65362
65600
|
});
|
|
65363
|
-
nextIndex = index + rowCount;
|
|
65364
|
-
totalSignal.value = nextIndex;
|
|
65365
|
-
return index;
|
|
65366
65601
|
}
|
|
65367
65602
|
};
|
|
65368
65603
|
return virtual;
|
|
65369
65604
|
};
|
|
65605
|
+
const sameSlotIds = (left, right) => {
|
|
65606
|
+
if (left.length !== right.length) {
|
|
65607
|
+
return false;
|
|
65608
|
+
}
|
|
65609
|
+
let index = 0;
|
|
65610
|
+
while (index < left.length) {
|
|
65611
|
+
if (left[index] !== right[index]) {
|
|
65612
|
+
return false;
|
|
65613
|
+
}
|
|
65614
|
+
index++;
|
|
65615
|
+
}
|
|
65616
|
+
return true;
|
|
65617
|
+
};
|
|
65618
|
+
|
|
65619
|
+
// The walk that gives the list's children their places: a slot for each of
|
|
65620
|
+
// them, declared to the list's virtual all at once before any child renders,
|
|
65621
|
+
// and handed to the child through a provider of its own — which is what lets
|
|
65622
|
+
// the row reach it however deep the caller buried it in components of theirs.
|
|
65623
|
+
//
|
|
65624
|
+
// A slot is named the way preact tells the child apart: by key when it has
|
|
65625
|
+
// one, by position otherwise, and inside the array it was given in — a nested
|
|
65626
|
+
// array is one child to preact, so what follows the array keeps its name
|
|
65627
|
+
// however many rows the array holds. A child preact would not render (null,
|
|
65628
|
+
// a boolean) has no slot: it is not there.
|
|
65629
|
+
const ListDeclaredChildren = ({
|
|
65630
|
+
children
|
|
65631
|
+
}) => {
|
|
65632
|
+
const virtual = useContext(ListVirtualContext);
|
|
65633
|
+
const parentSlotId = useContext(ListSlotContext);
|
|
65634
|
+
if (parentSlotId !== null && virtual.slotHasOwner(parentSlotId)) {
|
|
65635
|
+
return children;
|
|
65636
|
+
}
|
|
65637
|
+
const slotIds = [];
|
|
65638
|
+
const declared = [];
|
|
65639
|
+
declareChildren(children, parentSlotId === null ? "" : `${parentSlotId}/`, slotIds, declared);
|
|
65640
|
+
virtual.declareSlots(parentSlotId, slotIds);
|
|
65641
|
+
return jsx(Fragment$1, {
|
|
65642
|
+
children: declared
|
|
65643
|
+
});
|
|
65644
|
+
};
|
|
65645
|
+
const declareChildren = (children, prefix, slotIds, declared) => {
|
|
65646
|
+
const childArray = Array.isArray(children) ? children : [children];
|
|
65647
|
+
let index = 0;
|
|
65648
|
+
for (const child of childArray) {
|
|
65649
|
+
if (Array.isArray(child)) {
|
|
65650
|
+
declareChildren(child, `${prefix}${index}/`, slotIds, declared);
|
|
65651
|
+
} else if (child !== null && child !== undefined && child !== false && child !== true) {
|
|
65652
|
+
const slotId = child.key === undefined || child.key === null ? `${prefix}i${index}` : `${prefix}k${child.key}`;
|
|
65653
|
+
slotIds.push(slotId);
|
|
65654
|
+
declared.push(jsx(ListSlotContext.Provider, {
|
|
65655
|
+
value: slotId,
|
|
65656
|
+
children: child
|
|
65657
|
+
}, slotId));
|
|
65658
|
+
}
|
|
65659
|
+
index++;
|
|
65660
|
+
}
|
|
65661
|
+
};
|
|
65370
65662
|
const VISIBILITY_HIDDEN_STYLE = {
|
|
65371
65663
|
visibility: "hidden"
|
|
65372
65664
|
};
|
|
@@ -65501,6 +65793,7 @@ const ListItems = ({
|
|
|
65501
65793
|
}) => {
|
|
65502
65794
|
const ownerId = useId();
|
|
65503
65795
|
const virtual = useContext(ListVirtualContext);
|
|
65796
|
+
const slotId = useContext(ListSlotContext);
|
|
65504
65797
|
const renderWindow = useContext(RenderWindowContext);
|
|
65505
65798
|
const separator = useContext(SeparatorContext);
|
|
65506
65799
|
const store = useItemStore({
|
|
@@ -65522,7 +65815,7 @@ const ListItems = ({
|
|
|
65522
65815
|
skeletonRow.rowMinHeight = `${virtualItemSize}px`;
|
|
65523
65816
|
}
|
|
65524
65817
|
}
|
|
65525
|
-
const runStart = virtual.take(ownerId, store.rowCount);
|
|
65818
|
+
const runStart = virtual.take(ownerId, store.rowCount, slotId);
|
|
65526
65819
|
const runEnd = runStart + store.rowCount;
|
|
65527
65820
|
const getItemAt = index => store.getItem(index);
|
|
65528
65821
|
const windowFrom = renderWindow.start > runStart ? renderWindow.start : runStart;
|
|
@@ -65549,6 +65842,7 @@ const ListItems = ({
|
|
|
65549
65842
|
useLayoutEffect(() => {
|
|
65550
65843
|
return () => {
|
|
65551
65844
|
virtual.dropRowLocator(ownerId);
|
|
65845
|
+
virtual.drop(ownerId);
|
|
65552
65846
|
};
|
|
65553
65847
|
}, []);
|
|
65554
65848
|
|
|
@@ -66334,7 +66628,9 @@ const ListItemGroup = ({
|
|
|
66334
66628
|
"aria-labelledby": groupId,
|
|
66335
66629
|
children: jsx(GroupItemTrackerContext.Provider, {
|
|
66336
66630
|
value: groupTracker,
|
|
66337
|
-
children:
|
|
66631
|
+
children: jsx(ListDeclaredChildren, {
|
|
66632
|
+
children: children
|
|
66633
|
+
})
|
|
66338
66634
|
})
|
|
66339
66635
|
})]
|
|
66340
66636
|
});
|