Events

Try interacting with the list below and check the event log below.

Scroll to row index
Scroll to pixel offset
Visible Area: start 0 - end 0
Item #0
Item #1
Item #2
Item #3
Item #4
Item #5
Item #6
Item #7
Item #8
Item #9
Item #10
Item #11
Item #12
Item #13
Item #14
Item #15
<script lang="ts">
  import { VirtualList, type SlotAttributes } from 'svelte-virtuallists';
  import TextArea from '$comp/TextAreaAutosize.svelte';

  let val = $state('// Event name: Event params   (Last event at the top)');

  let start = $state(0);
  let end = $state(0);

  function handleMessage(event: any) {
    val = JSON.stringify(event) + '\n' + val;

    if (event.type === 'range.update') {
      start = event.start;
      end = event.end;
    }
  }

  // that's the model, which we don't use for this example
  const myModel: Array<number> = new Array(10000).fill(1).map((v, i) => i);

  let virtualList: VirtualList;

  // on the UI
  let theScrollToIndex: number | undefined = $state();
  let theScrollOffet: number | undefined = $state();

  // on the component
  let scrollToIndex: number | undefined = $state();
  let scrollOffet: number | undefined = $state();

  $effect(() => {
    // scrollToIndex and scrollOffset shall not be used together.
    scrollToIndex = undefined;
    scrollOffet = theScrollOffet;
  });

  $effect(() => {
    // scrollToIndex and scrollOffset shall not be used together.
    scrollOffet = undefined;
    scrollToIndex = theScrollToIndex;
  });
</script>

<TextArea value={val} minRows={4} maxRows={15} />

<div class="actions">
  <div class="select">
    <span>
      Scroll to row index
      <input
        id="index"
        type="number"
        placeholder="pick an index..."
        class="input"
        bind:value={theScrollToIndex} />
    </span>
  </div>
  <div class="select">
    <span>
      Scroll to pixel offset
      <input
        id="offset"
        type="number"
        placeholder="pick an offset..."
        class="input"
        bind:value={theScrollOffet} />
    </span>
  </div>
</div>
<div style="float: right;font-weight: bold">
  <span>Visible Area: start</span>
  <span>{start}</span>
  -
  <span>end</span>
  <span>{end}</span>
</div>
<div class="list">
  <VirtualList
    bind:this={virtualList}
    height={500}
    width="auto"
    model={myModel}
    modelCount={myModel.length}
    itemSize={40}
    {scrollToIndex}
    scrollOffset={scrollOffet}
    onAfterScroll={handleMessage}
    onVisibleRangeUpdate={handleMessage}>
    {#snippet slot({ item, style, index }: SlotAttributes<any>)}
      <div class="row" {style} class:highlighted={index === scrollToIndex}>
        Item #{item}
      </div>
    {/snippet}
  </VirtualList>
</div>

<style>
  :global(body),
  :global(html) {
    height: 100%;
    margin: 0;
    background-color: rgb(249, 249, 249);
    display: block;
  }

  :global(.virtual-list-wrapper) {
    margin: 20px;
    background: #fff;
    border-radius: 2px;
    background: #fafafa;
    font-family: -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif;
    color: #333;
    -webkit-font-smoothing: antialiased;
  }

  .row {
    padding: 0 15px;
    border-bottom: 1px solid #eee;
    box-sizing: border-box;
    line-height: 50px;
    font-weight: 500;
    background: #fff;
  }

  .row.highlighted {
    background: #efefef;
  }
</style>
next Styles
Direction: