mrshanebarron / infinite-scroll
Infinite scroll component for Laravel - supports Livewire and Vue
v1.0.4
2025-12-16 00:57 UTC
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0|^12.0
README
An infinite scrolling component for Laravel applications. Automatically loads more content as user scrolls. Works with Livewire and Vue 3.
Installation
composer require mrshanebarron/infinite-scroll
Livewire Usage
Basic Usage
<livewire:sb-infinite-scroll :loading="$loading" :no-more="$noMore"> @foreach($items as $item) <div class="p-4 border-b">{{ $item->title }}</div> @endforeach </livewire:sb-infinite-scroll>
Livewire Props
| Prop | Type | Default | Description |
|---|---|---|---|
loading |
boolean | false |
Currently loading |
no-more |
boolean | false |
No more items |
threshold |
number | 100 |
Scroll threshold in px |
root-margin |
string | '100px' |
IntersectionObserver margin |
Vue 3 Usage
Setup
import { SbInfiniteScroll } from './vendor/sb-infinite-scroll'; app.component('SbInfiniteScroll', SbInfiniteScroll);
Basic Usage
<template> <SbInfiniteScroll :loading="loading" :no-more="noMore" @load-more="loadMore" > <div v-for="item in items" :key="item.id" class="p-4 border-b"> {{ item.title }} </div> </SbInfiniteScroll> </template> <script setup> import { ref } from 'vue'; const items = ref([]); const loading = ref(false); const noMore = ref(false); const page = ref(1); const loadMore = async () => { loading.value = true; const response = await fetch(`/api/items?page=${page.value}`); const data = await response.json(); items.value.push(...data.items); noMore.value = data.items.length === 0; page.value++; loading.value = false; }; // Initial load loadMore(); </script>
Feed Example
<template> <div class="max-w-2xl mx-auto"> <SbInfiniteScroll :loading="loading" :no-more="noMore" @load-more="loadPosts" > <article v-for="post in posts" :key="post.id" class="p-6 bg-white rounded-lg shadow mb-4" > <h2 class="text-xl font-bold">{{ post.title }}</h2> <p class="text-gray-600 mt-2">{{ post.excerpt }}</p> </article> <template #loading> <div class="text-center py-4"> <span class="text-gray-500">Loading more posts...</span> </div> </template> <template #no-more> <div class="text-center py-4"> <span class="text-gray-400">You've reached the end!</span> </div> </template> </SbInfiniteScroll> </div> </template>
Vue Props
| Prop | Type | Default | Description |
|---|---|---|---|
loading |
Boolean | false |
Loading state |
noMore |
Boolean | false |
No more items to load |
threshold |
Number | 100 |
Scroll threshold |
rootMargin |
String | '100px' |
Observer margin |
Events
| Event | Payload | Description |
|---|---|---|
load-more |
- | Triggered when scroll reaches threshold |
Slots
| Slot | Description |
|---|---|
| default | Content items |
loading |
Custom loading indicator |
no-more |
End of list message |
Features
- Intersection Observer: Efficient scroll detection
- Loading State: Shows spinner while loading
- End Detection: Displays message when no more items
- Customizable: Custom loading and end slots
- Preloading: Configurable load threshold
Styling
Uses Tailwind CSS:
- Spinner animation
- Centered loading/end messages
- Gray text for status
Requirements
- PHP 8.1+
- Laravel 10, 11, or 12
- Tailwind CSS 3.x
License
MIT License