Quick Start
If you don't want to use Infinite's features, use @egjs/grid.
- JavaScript
 - React
 - Vue@2
 - Vue@3
 - Angular
 - Svelte
 
Add the script/CSS to the page.
<!-- https://naver.github.io/egjs-infinitegrid/release/latest/dist/infinitegrid.min.js -->
<script src="https://unpkg.com/@egjs/infinitegrid/dist/infinitegrid.min.js" crossorigin="anonymous"></script>
Or, you can rather import them if you're using a bundler like webpack or rollup.
import { MasonryInfiniteGrid } from "@egjs/infinitegrid";
Then, add some basic HTML layout of InfiniteGrid to your page.
<div class="wrapper">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
Then initialize InfiniteGrid instance with JavaScript after.
import { MasonryInfiniteGrid } from "@egjs/infinitegrid";
const ig = new MasonryInfiniteGrid(".wrapper", {
  align: "center",
  gap: 5,
});
ig.on("requestAppend", e => {
  const nextGroupKey = (e.groupKey || 0) + 1;
  const length = items.length;
  ig.append([
    `<div class="item">${length}</div>`,
    `<div class="item">${length + 1}</div>`,
    `<div class="item">${length + 2}</div>`,
  ], nextGroupKey);
});
ig.renderItems();
You can import & use InfiniteGrid as a React Component.
SomeComponent.jsx
import * as React from "react";
import { MasonryInfiniteGrid } from "@egjs/react-infinitegrid";
export default () => {
  const [items, setItems] = React.useState([]);
  return <MasonryInfiniteGrid
    align="center"
    gap={5}
    onRequestAppend={e => {
      const nextGroupKey = (e.groupKey || 0) + 1;
      const length = items.length;
      setItems([
        ...items,
        { groupKey: nextGroupKey, key: length },
        { groupKey: nextGroupKey, key: length + 1 },
        { groupKey: nextGroupKey, key: length + 2 },
      ]);
    }}>
    {items.map((item) => {
      return <div className="item" data-grid-groupkey={item.groupKey} key={item.key}>{item.key}</div>
    })}
  </MasonryInfiniteGrid>;
}
You can import & use InfiniteGrid as a Vue Component.
<template>
<masonry-infinite-grid
  class="container"
  v-bind:gap="5"
  v-on:requestAppend="onRequestAppend"
>
  <div
    class="item"
    v-for="item in items"
    :key="item.key"
    :data-grid-groupkey="item.groupKey"
  >{{ item.key }}</div>
</masonry-infinite-grid>
<script>
import { MasonryInfiniteGrid } from "@egjs/vue-infinitegrid";
export default {
  components: {
    MasonryInfiniteGrid,
  },
  data() {
    return {
      items: [],
    };
  },
  methods: {
    onRequestAppend(e) {
      const nextGroupKey = (e.groupKey || 0) + 1;
      const length = this.items.length;
      this.items = [
        ...this.items,
        { groupKey: nextGroupKey, key: length },
        { groupKey: nextGroupKey, key: length + 1 },
        { groupKey: nextGroupKey, key: length + 2 },
      ];
    },
  },
};
You can import & use InfiniteGrid as a Vue Component.
<template>
<masonry-infinite-grid
  class="container"
  v-bind:gap="5"
  v-on:requestAppend="onRequestAppend"
>
  <div
    class="item"
    v-for="item in items"
    :key="item.key"
    :data-grid-groupkey="item.groupKey"
  >{{ item.key }}</div>
</masonry-infinite-grid>
<script>
import { MasonryInfiniteGrid } from "@egjs/vue3-infinitegrid";
export default {
  components: {
    MasonryInfiniteGrid,
  },
  data() {
    return {
      items: [],
    };
  },
  methods: {
    onRequestAppend(e) {
      const nextGroupKey = (e.groupKey || 0) + 1;
      const length = this.items.length;
      this.items = [
        ...this.items,
        { groupKey: nextGroupKey, key: length },
        { groupKey: nextGroupKey, key: length + 1 },
        { groupKey: nextGroupKey, key: length + 2 },
      ];
    },
  },
};
You can add NgxInfiniteGridModule at imports of your app module to use InfiniteGrid.
app.module.ts
import { NgxInfiniteGridModule } from '@egjs/ngx-infinitegrid';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    NgxInfiniteGridModule /* Add in imports */
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { } /* Your app */
app.component.html
<div NgxMasonryInfiniteGrid
  [items]="items"
  [trackBy]="trackBy"
  [groupBy]="groupBy"
  [gap]="5"
  (requestAppend)="onRequestAppend($event)"
  #ig
  >
  <div class="item" *ngFor ="let item of ig.visibleItems; trackBy: trackBy;">
    {{item.data.key}}
  </div>
</div>
app.component.ts
import { Component, Input } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {
  items = [];
  groupBy(_: any, item: any) {
    return item.groupKey;
  }
  trackBy(_: any, item: any) {
    return item.key;
  }
  onRequestAppend(e) {
    const nextGroupKey = (e.groupKey || 0) + 1;
    const length = this.items.length;
    this.items = [
      ...this.items,
      { groupKey: nextGroupKey, key: length },
      { groupKey: nextGroupKey, key: length + 1 },
      { groupKey: nextGroupKey, key: length + 2 },
    ];
  }
}
You can import InfiniteGrid from the "@egjs/svelte-infinitegrid" package.
App.svelte
<script lang="ts">
  import { MasonryInfiniteGrid } from "@egjs/svelte-infinitegrid";
  let items = [];
</script>
<MasonryInfiniteGrid
  class="container"
  gap={5}
  {items}
  on:requestAppend={({ detail: e }) => {
    const nextGroupKey = (e.groupKey || 0) + 1;
    const length = items.length;
    items = [
      ...items,
      { groupKey: nextGroupKey, key: length },
      { groupKey: nextGroupKey, key: length + 1 },
      { groupKey: nextGroupKey, key: length + 2 },
    ];
  }}
  let:visibleItems
>
   {#each visibleItems as item (item.key)}
    <div class="item">
     {item.data.key}
    </div>
  {/each}
</MasonryInfiniteGrid>