Decorative clouds
# Vue-Infinity *Build lightning-fast Vue apps that only render what is on-screen* Vue-Infinity brings a radical efficiency boost to your UI by applying the same principle that powers 3D engines: if it’s not in visible, it doesn’t get rendered. This lets your app handle hundreds or thousands of elements without bloating memory, janking or killing batteries. Whether you’re building infinite feeds, carousels, media galleries, or dashboards—Vue-Infinity keeps your app fast, smooth, and efficient. ## Table of Contents - [Monorepo Structure](#-monorepo-structure) - [Gallery Web Component](#-gallery-web-component) - [Carousel Component](#-carousel-component) - [InfiniteCarousel](#-infinitecarousel) - [Ghost Component](#-ghost-component) - [AutoObserver](#-autoobserver) - [Installation](#-installation) - [Live Demo](#-live-demo) - [Development](#-development) - [Releases](#releases) - [License](#-license) ## 🏗️ Monorepo Structure This project is organized as an Nx monorepo with two packages and two demo apps: | Package | npm Name | Description | |---------|----------|-------------| | `packages/core` | `vue-infinity` (published) / `vue-infinity` (workspace) | Core Vue 3 components: Carousel, InfiniteCarousel, Ghost, AutoObserver, composables | | `packages/elements` | `@vue-infinity/elements` | Framework-agnostic custom elements (web components) built on the core package | | App | Command | Description | |-----|---------|-------------| | `apps/demo-vue` | `npm run dev:core` | Vue demo showcasing core components with live controls | | `apps/demo-elements` | `npm run dev:elements` | Custom elements demo showcasing the `` web component | ## 🖼️ Gallery Web Component The `gallery-ce` is a web component built on top of the Carousel component that provides an easy way to display a gallery of images with features like lazy loading, responsive layout, and dynamic sizing. It's designed to efficiently handle large collections of images while maintaining smooth performance. - **Easy to use**: Suitable when you have a big static list of images you want to browse - **Framework agnostic**: Can be used without Vue in any framework or vanilla JavaScript - **Flexible Layout**: Configurable grid layout with customizable columns and rows - **Lazy Loading**: Only renders visible images for optimal performance ### Usage Examples #### Plain JavaScript ```html ``` #### React ```jsx import { useEffect, useRef } from 'react'; import { registerElements } from '@vue-infinity/elements'; registerElements(); function Gallery() { const galleryRef = useRef(null); useEffect(() => { if (galleryRef.current) { galleryRef.current.updateImages([ 'image1.jpg', 'image2.jpg', 'image3.jpg' ]); } }, []); return ; } ``` #### Svelte ```svelte ``` #### Vue ```vue ``` ### Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `items` | String (JSON) | `'[]'` | Array of image URLs or objects with `url`, `title`, and `alt` properties | | `height` | String | `'400px'` | Height of the gallery container | | `width` | String | `'100%'` | Width of the gallery container | | `num-cols-to-show` | Number | `1` | Number of columns to show (can be fractional for partial items) | | `num-rows-to-show` | Number | `1` | Number of rows to show | | `gap` | String | `'1rem'` | Gap between items | | `vertical-scroll` | Boolean | `false` | Whether to scroll vertically instead of horizontally | ### Methods | Method | Parameters | Description | |--------|------------|-------------| | `updateImages` | `newItems` (Array or JSON string) | Update the gallery with new images | | `scrollToItem` | `itemIndex` (Number) | Scroll to a specific item by index | **Note:** The `registerElements()` function must be called once before using any `@vue-infinity/elements` web components. ## 🎠 Carousel Component The Carousel component works like the Gallery but for any type of content. It provides a flexible way to display any kind of content in a carousel layout with lazy loading and responsive design. ```vue ``` ## 🪂 InfiniteCarousel The InfiniteCarousel works like the Carousel but with the ability to fetch more data as the user scrolls. It integrates with the `useInfiniteList` composable to handle data fetching and caching. ### Creating an InfiniteList ```javascript import { useInfiniteList } from 'vue-infinity'; const infiniteList = useInfiniteList({ fetchItems: async (page, signal) => { const response = await fetch(`/api/items?page=${page}`, { signal }); return response.json(); }, itemsPerPage: 50, maxPagesToCache: 5 }); ``` ### Using with InfiniteList ```vue ``` ## 👻 Ghost Component The Ghost component is useful when you want to apply visibility based rendering to anything. It optimizes performance by conditionally rendering its slot content. When off-screen, the content is replaced by a dimensionally-identical placeholder. ### Component Usage ```vue ``` ### Directive Usage ```vue ``` ## 🔎 AutoObserver The AutoObserver combines a MutationObserver and IntersectionObserver to allow you to track a container's child elements. It automatically handles new elements and cleaning up removed ones. - Get notified when elements get added - Get notified when elements become visible or when they are scrolled out of view ```javascript const containerRef = ref(); const { disconnect } = useAutoObserver( containerRef, (entries) => { entries.forEach(entry => { console.log('Element visibility changed:', entry.isIntersecting); }); }, { rootMargin: '200px', threshold: 0.1, filter: el => el.classList.contains('observe-me') } ); ``` ## 📦 Installation ```bash # Core Vue components (for use within Vue apps) npm install vue-infinity # Custom elements (for framework-agnostic usage) npm install @vue-infinity/elements ``` ## 🧪 Live Demo Explore the live demo here: [https://tewolde.co/vueInfinity/](https://tewolde.co/vueInfinity/) ## 🧑‍💻 Development To run the demos and build the packages locally: ```bash # Core Vue demo (Carousel, Ghost, InfiniteCarousel) npm run dev:core # Custom elements demo (Gallery web component) npm run dev:elements # Build all packages npm run build # Run all tests npm test ``` ## Releases ### v0.8.6 (2026-01-14) #### API Changes **InfiniteCarousel Component**: - Changed `startingPosition` prop to `startingIndex` for clarity - Added `scrollPosition` event emit to track scroll position as a fraction (0-1) - Added two-way binding support for `scrollPosition` via `v-model:scrollPosition` - Updated Playground app to reflect these changes ### v0.8.5 (2025-12-10) #### Bug Fixes **InfiniteCarousel Component**: - Fixed issue where updating `startingPosition` did not scroll to the correct item ### v0.8.4 (2025-11-26) #### Enhancements **InfiniteCarousel Component**: - Added `startingPosition` prop with two-way binding support (`v-model:startingPosition`) - Integrated `useSortedElements` composable for improved top-left item detection **Playground App**: - Updated to show `startingPosition` control for InfiniteCarousel ### v0.8.0 (2025-08-11) #### New Components and Features **Gallery Web Component**: - Simple: Easy to use web component for displaying image galleries with lazy loading, responsive layout and memory efficiency. - Framework Agnostic: Use in any frontend framework or even plain JavaScript. - Flexible: Methods to update images and scroll to specific items - Package: The Gallery Web Component now lives in the `@vue-infinity/elements` package. - Playground App: Added a demo for the Gallery component in the playground app. - Documentation Updates: Added comprehensive examples for Vue, React, Svelte, and plain JavaScript **Carousel Component**: - Similar to the Gallery but for any type of content. - Supports lazy loading, easy layout and memory efficiency. - Supports custom item templates and dynamic content sizing. ### v0.7.0 (2024-07-01) - **v-ghost Directive**: Introduced the new `v-ghost` directive to optimize performance by automatically unloading off-screen content. - **Dynamic Item Sizing**: The `InfiniteCarousel` now supports an `onGetItemAspectRatio` callback, enabling it to render items with variable heights. - **Documentation Updates**: Added instructions for the `v-ghost` directive and the dynamic sizing feature. ## 📄 License Apache 2.0 License - [https://opensource.org/licenses/Apache-2.0](https://opensource.org/licenses/Apache-2.0)