virtua 0.41.0 → 0.41.2

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.
@@ -1,4 +1,4 @@
1
- import { mergeProps, createEffect, onCleanup, createMemo, createSignal, onMount, createComputed, on, For, untrack } from 'solid-js';
1
+ import { mergeProps, createEffect, onCleanup, createMemo, createSignal, onMount, createComputed, on, untrack, For, splitProps } from 'solid-js';
2
2
  import { Dynamic } from 'solid-js/web';
3
3
 
4
4
  /** @internal */
@@ -1272,7 +1272,7 @@ const ListItem = (props) => {
1272
1272
  }
1273
1273
  return style;
1274
1274
  });
1275
- return (<Dynamic component={props._as} ref={elementRef} style={style()}>
1275
+ return (<Dynamic component={props._as} index={props._index} ref={elementRef} style={style()}>
1276
1276
  {props._children}
1277
1277
  </Dynamic>);
1278
1278
  };
@@ -1357,11 +1357,6 @@ const Virtualizer = (props) => {
1357
1357
  scroller.$dispose();
1358
1358
  });
1359
1359
  });
1360
- createComputed(on(() => props.data.length, (count) => {
1361
- if (count !== store.$getItemsLength()) {
1362
- store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);
1363
- }
1364
- }));
1365
1360
  createComputed(on(() => props.startMargin || 0, (value) => {
1366
1361
  if (value !== store.$getStartSpacerSize()) {
1367
1362
  store.$update(ACTION_START_OFFSET_CHANGE, value);
@@ -1371,9 +1366,53 @@ const Virtualizer = (props) => {
1371
1366
  scroller.$fixScrollJump();
1372
1367
  }));
1373
1368
  const dataSlice = createMemo(() => {
1369
+ const count = props.data.length;
1370
+ untrack(() => {
1371
+ if (count !== store.$getItemsLength()) {
1372
+ store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);
1373
+ }
1374
+ });
1374
1375
  const [start, end] = range();
1375
- return end >= 0 ? props.data.slice(start, end + 1) : [];
1376
+ const items = end >= 0 ? props.data.slice(start, end + 1) : [];
1377
+ const indexes = items.map((_, index) => start + index);
1378
+ if (props.keepMounted) {
1379
+ const startItems = [];
1380
+ const startIndexes = [];
1381
+ const endItems = [];
1382
+ const endIndexes = [];
1383
+ sort(props.keepMounted).forEach((index) => {
1384
+ if (index < 0 || index >= props.data.length)
1385
+ return;
1386
+ if (index < start) {
1387
+ startItems.push(props.data[index]);
1388
+ startIndexes.push(index);
1389
+ }
1390
+ if (index > end) {
1391
+ endItems.push(props.data[index]);
1392
+ endIndexes.push(index);
1393
+ }
1394
+ });
1395
+ items.unshift(...startItems);
1396
+ indexes.unshift(...startIndexes);
1397
+ items.push(...endItems);
1398
+ indexes.push(...endIndexes);
1399
+ }
1400
+ return { _items: items, _indexes: indexes };
1376
1401
  });
1402
+ const renderItem = (data, index) => {
1403
+ const offset = createMemo(() => {
1404
+ stateVersion();
1405
+ return store.$getItemOffset(index());
1406
+ });
1407
+ const hide = createMemo(() => {
1408
+ stateVersion();
1409
+ return store.$isUnmeasuredItem(index());
1410
+ });
1411
+ const children = createMemo(() => {
1412
+ return untrack(() => props.children(data, index));
1413
+ });
1414
+ return (<ListItem _as={props.item} _index={index()} _resizer={resizer.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal}/>);
1415
+ };
1377
1416
  return (<Dynamic component={props.as} ref={containerRef} style={{
1378
1417
  // contain: "content",
1379
1418
  "overflow-anchor": "none", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer
@@ -1384,41 +1423,48 @@ const Virtualizer = (props) => {
1384
1423
  height: horizontal ? "100%" : totalSize() + "px",
1385
1424
  "pointer-events": isScrolling() ? "none" : undefined,
1386
1425
  }}>
1387
- <For each={dataSlice()}>
1426
+ <For each={dataSlice()._items}>
1388
1427
  {(data, index) => {
1389
- const itemIndex = createMemo(() => range()[0] + index());
1390
- const offset = createMemo(() => {
1391
- stateVersion();
1392
- return store.$getItemOffset(itemIndex());
1393
- });
1394
- const hide = createMemo(() => {
1395
- stateVersion();
1396
- return store.$isUnmeasuredItem(itemIndex());
1397
- });
1398
- const children = createMemo(() => {
1399
- return untrack(() => props.children(data, itemIndex));
1400
- });
1401
- return (<ListItem _as={props.item} _index={itemIndex()} _resizer={resizer.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal}/>);
1428
+ const itemIndex = createMemo(() => dataSlice()._indexes[index()]);
1429
+ // eslint-disable-next-line solid/reactivity
1430
+ return renderItem(data, itemIndex);
1402
1431
  }}
1403
1432
  </For>
1404
1433
  </Dynamic>);
1405
1434
  };
1406
1435
 
1436
+ /**
1437
+ * @jsxImportSource solid-js
1438
+ */
1407
1439
  /**
1408
1440
  * Virtualized list component. See {@link VListProps} and {@link VListHandle}.
1409
1441
  */
1410
1442
  const VList = (props) => {
1411
- const { ref, data, children, overscan, itemSize, shift, horizontal, cache, onScroll, onScrollEnd, style, ...attrs } = props;
1412
- return (<div {...attrs} style={{
1413
- display: horizontal ? "inline-block" : "block",
1414
- [horizontal ? "overflow-x" : "overflow-y"]: "auto",
1443
+ const [local, others] = splitProps(props, [
1444
+ "ref",
1445
+ "data",
1446
+ "children",
1447
+ "overscan",
1448
+ "itemSize",
1449
+ "shift",
1450
+ "horizontal",
1451
+ "keepMounted",
1452
+ "cache",
1453
+ "item",
1454
+ "onScroll",
1455
+ "onScrollEnd",
1456
+ "style",
1457
+ ]);
1458
+ return (<div {...others} style={{
1459
+ display: local.horizontal ? "inline-block" : "block",
1460
+ [local.horizontal ? "overflow-x" : "overflow-y"]: "auto",
1415
1461
  contain: "strict",
1416
1462
  width: "100%",
1417
1463
  height: "100%",
1418
- ...props.style,
1464
+ ...local.style,
1419
1465
  }}>
1420
- <Virtualizer ref={props.ref} data={props.data} overscan={props.overscan} itemSize={props.itemSize} shift={props.shift} horizontal={horizontal} cache={cache} onScroll={props.onScroll} onScrollEnd={props.onScrollEnd}>
1421
- {props.children}
1466
+ <Virtualizer ref={local.ref} data={local.data} overscan={local.overscan} itemSize={local.itemSize} shift={local.shift} horizontal={local.horizontal} keepMounted={local.keepMounted} cache={local.cache} item={local.item} onScroll={local.onScroll} onScrollEnd={local.onScrollEnd}>
1467
+ {local.children}
1422
1468
  </Virtualizer>
1423
1469
  </div>);
1424
1470
  };
@@ -1482,15 +1528,16 @@ const WindowVirtualizer = (props) => {
1482
1528
  scroller.$dispose();
1483
1529
  });
1484
1530
  });
1485
- createComputed(on(() => props.data.length, (len) => {
1486
- if (len !== store.$getItemsLength()) {
1487
- store.$update(ACTION_ITEMS_LENGTH_CHANGE, [len, props.shift]);
1488
- }
1489
- }));
1490
1531
  createEffect(on(stateVersion, () => {
1491
1532
  scroller.$fixScrollJump();
1492
1533
  }));
1493
1534
  const dataSlice = createMemo(() => {
1535
+ const count = props.data.length;
1536
+ untrack(() => {
1537
+ if (count !== store.$getItemsLength()) {
1538
+ store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);
1539
+ }
1540
+ });
1494
1541
  const [start, end] = range();
1495
1542
  return end >= 0 ? props.data.slice(start, end + 1) : [];
1496
1543
  });