Here's a sample README.md
file that provides detailed instructions on how to install, use, and customize your WyxosMasonry
plugin.
# WyxosMasonry - Vue 3 Masonry Layout Component
**WyxosMasonry** is a customizable and easy-to-use Vue 3 component for creating infinite scrolling, masonry-style layouts. It supports lazy loading, customizable item rendering, and flexible styling options, making it a great choice for building media-rich or dynamic grid layouts.
## Features
- **Infinite scrolling** with support for loading more pages dynamically.
- **Customizable grid layout**: You can fully control the HTML structure and styling of items.
- **Smooth transitions** for adding, removing, and moving items.
- **Slot-based customization**: Easily change the appearance of grid items, loaders, and buttons.
## Installation
Install the component via npm:
```bash
npm install wyxos-masonry
Here’s how to set up a simple masonry layout with infinite scrolling and item removal functionality:
<template>
<div>
<wyxos-masonry
:load="load"
:load-next="loadNext"
:load-previous="loadPrevious"
:pages="pages"
@updatePages="handleUpdatePages"
>
<!-- Customize how each item is displayed -->
<template #item="{ item, onRemove }">
<div class="item-card">
<img :src="item.src" :alt="item.title" />
<p>{{ item.title }}</p>
<button @click="onRemove(item)">Remove</button>
</div>
</template>
<!-- Customize loader -->
<template #loader>
<p>Loading more items...</p>
</template>
<!-- Customize the load more button -->
<template #load-more-button>
<button class="load-more-btn">Load More</button>
</template>
</wyxos-masonry>
</div>
</template>
<script>
import { ref } from 'vue';
import WyxosMasonry from 'wyxos-masonry';
export default {
components: { WyxosMasonry },
setup() {
const pages = ref([]);
const load = async () => {
// Load the initial set of items
return {
page: 1,
items: Array.from({ length: 48 }, (_, index) => ({
id: index,
key: `item-${index}`,
title: `Item ${index + 1}`,
src: `https://picsum.photos/200/200?random=${index}`,
})),
};
};
const loadNext = async () => {
// Load the next set of items
const nextPage = pages.value.length ? pages.value[pages.value.length - 1].page + 1 : 1;
return {
page: nextPage,
items: Array.from({ length: 48 }, (_, index) => ({
id: index,
key: `item-${nextPage}-${index}`,
title: `Item ${(nextPage - 1) * 48 + index + 1}`,
src: `https://picsum.photos/200/200?random=${index}`,
})),
};
};
const loadPrevious = async () => {
// Load the previous set of items if available
if (!pages.value.length || pages.value[0].page <= 1) return null;
const previousPage = pages.value[0].page - 1;
return {
page: previousPage,
items: Array.from({ length: 48 }, (_, index) => ({
id: index,
key: `item-${previousPage}-${index}`,
title: `Item ${(previousPage - 1) * 48 + index + 1}`,
src: `https://picsum.photos/200/200?random=${index}`,
})),
};
};
const handleUpdatePages = (updatedPages) => {
pages.value = updatedPages;
};
return {
pages,
load,
loadNext,
loadPrevious,
handleUpdatePages,
};
},
};
</script>
<style>
.item-card {
padding: 16px;
background-color: #fff;
border: 1px solid #e2e8f0;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
margin-bottom: 16px;
}
.load-more-btn {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: #4a90e2;
color: #fff;
border-radius: 5px;
border: none;
cursor: pointer;
}
.load-more-btn:hover {
background-color: #357ab8;
}
</style>
load
: A function to load the initial set of items.loadNext
: A function to load the next page of items.loadPrevious
: A function to load the previous page of items (optional).pages
: An array of objects representing the current pages and items.canLoadMore
: A boolean indicating if more items can be loaded (default:true
).
item
: Customize the rendering of each item in the grid. Receives anitem
object and anonRemove
function.loader
: Customize the content displayed while loading items.load-more-button
: Customize the "Load more" button.
You can fully customize the styling of the masonry layout by passing class names via props or by using scoped slots for specific areas.
containerClass
: Custom class for the main container.buttonClass
: Custom class for the "Load more" button.loaderClass
: Custom class for the loading indicator.gridItemClass
: Custom class for the grid items.
Example:
<wyxos-masonry
:load="load"
:load-next="loadNext"
:pages="pages"
container-class="custom-container"
button-class="custom-load-btn"
grid-item-class="custom-grid-item"
>
<template #item="{ item, onRemove }">
<div class="p-4 bg-gray-200">
<img :src="item.src" :alt="item.title" />
<p>{{ item.title }}</p>
<button @click="onRemove(item)" class="remove-btn">Remove</button>
</div>
</template>
</wyxos-masonry>
updatePages
: Emitted when the list of pages is updated. The updated pages array is passed as a parameter.
Feel free to fork this repository and submit pull requests for new features, improvements, or bug fixes.
MIT License
- Install instructions: Ensure the user knows how to install the plugin via npm and how to integrate it into their project.
- Usage example: Provide a basic usage example, including how to use slots and customize the layout.
- Props, slots, and events: Define the props, slots, and events that are available in the component.
- Customization section: Explain how users can customize the component's styling using props and scoped slots.
- License: Include licensing details for open-source sharing.
This README.md
should provide a solid foundation for users to quickly understand, install, and integrate your WyxosMasonry
component into their projects.