@wyxos/masonry
v1.1.3
Published
A masonry layout component for Vue 3.
Downloads
333
Readme
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
Usage
Basic Example
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>
Props
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
).
Slots
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.
Customization
You can fully customize the styling of the masonry layout by passing class names via props or by using scoped slots for specific areas.
Customizable Props
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>
Events
updatePages
: Emitted when the list of pages is updated. The updated pages array is passed as a parameter.
Contributing
Feel free to fork this repository and submit pull requests for new features, improvements, or bug fixes.
License
MIT License
How to Use the README.md
- 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.