modularavel / favoritable
A Laravel Livewire package to add favorites functionality to your application
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/modularavel/favoritable
Requires
- php: >=8.1
- illuminate/database: >=8.0
- illuminate/support: >=8.0
- livewire/livewire: ^3.0
Requires (Dev)
- orchestra/testbench: ^9.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
README
A Laravel Livewire package that adds favorites functionality to your Laravel 11+ application. Allow users to favorite any model in your application with a beautiful, customizable UI.
Features
- Add favorites to any Eloquent model
- Beautiful Livewire components with multiple variants
- Favorite button with counter
- Favorites list page
- Tailwind CSS styling included
- Full test coverage with Pest
- Easy to customize
- Real-time updates
Requirements
- PHP 8.2+
- Laravel 11.0+ or Laravel 12.0+
- Livewire 3.0+
- Tailwind CSS
Installation
Install the package via Composer:
composer require modularavel/favoritable
Publish the migrations:
php artisan vendor:publish --tag="modularavel:favoritable-migrations"
Run the migrations:
php artisan migrate
Optionally, publish the config file:
php artisan vendor:publish --tag="modularavel:favoritable-config"
Optionally, publish the views for customization:
php artisan vendor:publish --tag="modularavel:favoritable-views"
Setup
1. Add the Trait to Your Model
Add the Favoritable
trait to any model you want users to be able to favorite:
use Modularavel\Favoritable\Traits\HasModularavelFavoritable; class Post extends Model { use HasModularavelFavoritable; }
2. Import CSS Styles
Add the package CSS to your main CSS file or import it in your layout:
@import '../../vendor/modularavel/favoritable/resources/css/favoritable.css';
Or include it directly in your Tailwind config:
module.exports = { content: [ './vendor/modularavel/favoritable/resources/**/*.blade.php', ], }
Usage
Favorite Button Component
The simplest way to add a favorite button:
<livewire:favoritable-btn :model="$post" />
Button Variants
Choose from multiple button styles:
{{-- Default variant --}} <livewire:favoritable-btn :model="$post" variant="default" /> {{-- Outline variant --}} <livewire:favoritable-btn :model="$post" variant="outline" /> {{-- Solid variant --}} <livewire:favoritable-btn :model="$post" variant="solid" /> {{-- Icon only variant --}} <livewire:favoritable-btn :model="$post" variant="icon" />
Button Sizes
Choose from three sizes:
{{-- Small --}} <livewire:favoritable-btn :model="$post" size="sm" /> {{-- Medium (default) --}} <livewire:favoritable-btn :model="$post" size="md" /> {{-- Large --}} <livewire:favoritable-btn :model="$post" size="lg" />
Hide Counter
You can hide the favorites counter:
<livewire:favoritable-btn :model="$post" :show-count="false" />
Favorites List Component
Display a paginated list of user's favorites:
<livewire:favoritable-list />
Filter by Type
Show only favorites of a specific type:
<livewire:favoritable-list type="Post::class" />
Custom Pagination
<livewire:favoritable-list :per-page="20" />
Model Methods
The Favoritable
trait adds several helpful methods to your models:
// Check if favorited by a user $post->isFavoritedBy($user); // Toggle favorite $post->toggleFavorite($user); // Add favorite $post->addFavorite($user); // Remove favorite $post->removeFavorite($user); // Get favorites count $post->favoritesCount(); // Query scope for favorited items Post::favoritedBy($user)->get();
Customizing the Favorites List Display
To customize how your favorited items appear in the favorites list, implement these methods in your model:
class Post extends Model { use Favoritable; public function getFavoritableTitle(): string { return $this->title; } public function getFavoritableDescription(): ?string { return $this->excerpt; } public function getFavoritableImage(): ?string { return $this->featured_image; } public function getFavoritableUrl(): string { return route('posts.show', $this); } }
Configuration
The package includes a configuration file with sensible defaults:
return [ // The fully qualified class name of the user model 'user_model' => env('FAVORITABLE_USER_MODEL', 'App\\Models\\User'), // The name of the belongTo relationship on the favoritable model to the user model 'owner_relationship_name' => env('FAVORITABLE_OWNER_RELATIONSHIP_NAME', 'user'), // Button configuration 'button' => [ 'default_variant' => 'default', 'default_size' => 'md', 'show_count' => true, ], // List configuration 'list' => [ 'per_page' => 12, ], ];
Events
The package dispatches Livewire events that you can listen to:
favoriteToggled
Dispatched when a favorite is toggled:
Livewire.on('favoriteToggled', (data) => { console.log(data.modelType); console.log(data.modelId); console.log(data.isFavorited); });
Testing
The package includes comprehensive Pest tests. To run tests:
composer test
Styling
The package uses Tailwind CSS for styling. All styles are scoped to avoid conflicts with your application. You can customize the appearance by:
- Publishing the views and modifying the Blade templates
- Overriding the CSS classes in your application's CSS
- Modifying the published CSS file
Advanced Usage
Custom Favorite Model
If you need to extend the Favorite model:
use Modularavel\Favoritable\Models\Favorite as BaseFavorite; class Favorite extends BaseFavorite { // Your custom code }
Middleware Protection
Protect your favorites routes with middleware:
Route::middleware(['auth'])->group(function () { Route::get('/favorites', function () { return view('favorites'); }); });
License
MIT
Credits
- Modularavel
- All Contributors
Support
For issues, questions, or contributions, please visit the GitHub repository.