diff --git a/README.md b/README.md index 74d231d..e47a7ba 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Unsplash gallery for Filament. Search and pick any image from Unsplash.com, specify which size to use. -![](./screenshot.jpeg) +![](./screenshot.jpg) ## Installation @@ -97,6 +97,29 @@ Forms\Components\FileUpload::make('featured_image') ) ``` +# Enable/Disable Square Mode + +You can choose to dispaly images in square which uses `aspect-square` class from Tailwind CSS or disable it to display images in original height. + +Update use_square_display option in `.env` to apply this setting globally. + +```php +'use_square_display' => env('UNSPLASH_PICKER_USE_SQUARE_DISPLAY', true), +``` + +Or, You can disable this setting for each `UnsplashPickerAction` by appending `->useSquareDisplay(false)` method + +```php +Forms\Components\FileUpload::make('featured_image') + ->image() + ->hintAction( + UnsplashPickerAction::make() + ->thumbnail() + ->perPage(20) + ->useSquareDisplay(false) + ) +``` + ## Customization The `UnsplashPickerAction` is simple Filament Form Action and you append all the available methods. The Image picker component is a livewire component, you can extend and override the methods. diff --git a/config/unsplash-picker.php b/config/unsplash-picker.php index 89bf2cc..986cd5b 100644 --- a/config/unsplash-picker.php +++ b/config/unsplash-picker.php @@ -3,4 +3,5 @@ return [ 'unsplash_client_id' => env('UNSPLASH_CLIENT_ID'), 'per_page' => env('UNSPLASH_PICKER_PER_PAGE', 20), + 'use_square_display' => env('UNSPLASH_PICKER_USE_SQUARE_DISPLAY', true), ]; diff --git a/resources/dist/unsplash-picker.css b/resources/dist/unsplash-picker.css index b0a2023..c9c9cf0 100644 --- a/resources/dist/unsplash-picker.css +++ b/resources/dist/unsplash-picker.css @@ -1 +1 @@ -.columns-3{-moz-columns:3;column-count:3}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgba(var(--gray-900),var(--tw-bg-opacity))}.bg-opacity-60{--tw-bg-opacity:0.6}.opacity-25{opacity:.25}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.hover\:ring-2:hover{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.hover\:ring-primary-600:hover{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--primary-600),var(--tw-ring-opacity))}.hover\:ring-offset-2:hover{--tw-ring-offset-width:2px}.group:hover .group-hover\:flex{display:flex}:is(.dark .dark\:ring-white\/20){--tw-ring-color:#fff3}:is(.dark .dark\:hover\:ring-primary-500:hover){--tw-ring-opacity:1;--tw-ring-color:rgba(var(--primary-500),var(--tw-ring-opacity))}:is(.dark .dark\:hover\:ring-offset-black:hover){--tw-ring-offset-color:#000}@media (min-width:1024px){.lg\:columns-4{-moz-columns:4;column-count:4}} \ No newline at end of file +.aspect-square{aspect-ratio:1/1}.columns-3{-moz-columns:3;column-count:3}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgba(var(--gray-900),var(--tw-bg-opacity))}.bg-opacity-60{--tw-bg-opacity:0.6}.opacity-25{opacity:.25}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.hover\:ring-2:hover{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.hover\:ring-primary-600:hover{--tw-ring-opacity:1;--tw-ring-color:rgba(var(--primary-600),var(--tw-ring-opacity))}.hover\:ring-offset-2:hover{--tw-ring-offset-width:2px}.group:hover .group-hover\:flex{display:flex}:is(.dark .dark\:ring-white\/20){--tw-ring-color:#fff3}:is(.dark .dark\:hover\:ring-primary-500:hover){--tw-ring-opacity:1;--tw-ring-color:rgba(var(--primary-500),var(--tw-ring-opacity))}:is(.dark .dark\:hover\:ring-offset-black:hover){--tw-ring-offset-color:#000}@media (min-width:1024px){.lg\:columns-4{-moz-columns:4;column-count:4}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}} \ No newline at end of file diff --git a/resources/lang/en/actions.php b/resources/lang/en/actions.php deleted file mode 100644 index 788940b..0000000 --- a/resources/lang/en/actions.php +++ /dev/null @@ -1,5 +0,0 @@ - 'Pick from Unsplash', -]; diff --git a/resources/lang/en/unsplash-picker.php b/resources/lang/en/unsplash-picker.php index 23ab138..85c38e4 100644 --- a/resources/lang/en/unsplash-picker.php +++ b/resources/lang/en/unsplash-picker.php @@ -8,4 +8,5 @@ 'empty_search' => 'Please type in search box to find results.', 'no_results' => 'Sorry, your search didn\'t return any results.', 'try_again' => 'Please try a different search.', + 'square_mode' => 'Square Mode', ]; diff --git a/resources/views/livewire/unsplash-picker.blade.php b/resources/views/livewire/unsplash-picker.blade.php new file mode 100644 index 0000000..4ece84b --- /dev/null +++ b/resources/views/livewire/unsplash-picker.blade.php @@ -0,0 +1,69 @@ +
+
+ {{ $this->form }} +
+ +
+ @if (blank($search)) +

{{ __('unsplash-picker::unsplash-picker.empty_search') }}

+ @else +
+ filled($this->getImages) && $this->shouldUseSquareDisplay, + 'columns-3 space-y-4 lg:columns-4' => + filled($this->getImages) && !$this->shouldUseSquareDisplay, + ])> + @forelse ($this->getImages as $item) +
+ + $this->shouldUseSquareDisplay, + 'pointer-events-none w-full object-cover', + ]) + src="{{ $item['urls']['thumb'] }}" + > + + +
+ +
+ + +
+ @empty +
+

{{ __('unsplash-picker::unsplash-picker.no_results') }}

+

{{ __('unsplash-picker::unsplash-picker.try_again') }}

+
+ @endforelse +
+ @endif + + @if (filled($search) && count($this->getImages) > 0) +
+ {{ $this->previousPageAction }} + {{ $this->nextPageAction }} +
+ @endif +
+
diff --git a/resources/views/unsplash-picker.blade.php b/resources/views/unsplash-picker.blade.php index 60a7dfc..5e8bf8a 100644 --- a/resources/views/unsplash-picker.blade.php +++ b/resources/views/unsplash-picker.blade.php @@ -1,63 +1 @@ -
-
- {{ $this->form }} -
- -
- @if (blank($search)) -

{{ __('unsplash-picker::unsplash-picker.empty_search') }}

- @else -
filled($this->getImages), - ])> - @forelse ($this->getImages as $item) - - @empty -
-

{{ __('unsplash-picker::unsplash-picker.no_results') }}

-

{{ __('unsplash-picker::unsplash-picker.try_again') }}

-
- @endforelse -
- @endif - - @if (filled($search) && count($this->getImages) > 0) -
- {{ $this->previousPageAction }} - {{ $this->nextPageAction }} -
- @endif -
-
+@livewire('unsplash-picker-component', $options) diff --git a/screenshot.jpeg b/screenshot.jpeg deleted file mode 100644 index 63cde37..0000000 Binary files a/screenshot.jpeg and /dev/null differ diff --git a/screenshot.jpg b/screenshot.jpg new file mode 100644 index 0000000..53343d7 Binary files /dev/null and b/screenshot.jpg differ diff --git a/src/Actions/UnsplashPickerAction.php b/src/Actions/UnsplashPickerAction.php index 5eb380d..c49e3ed 100644 --- a/src/Actions/UnsplashPickerAction.php +++ b/src/Actions/UnsplashPickerAction.php @@ -8,8 +8,6 @@ use Filament\Forms\Components\FileUpload; use Filament\Support\Enums\MaxWidth; use Illuminate\Support\Arr; -use Illuminate\Support\Facades\Blade; -use Illuminate\Support\HtmlString; use Livewire\Component; use Livewire\Features\SupportFileUploads\FileUploadConfiguration; use Livewire\Features\SupportFileUploads\TemporaryUploadedFile; @@ -23,6 +21,8 @@ class UnsplashPickerAction extends Action protected ?int $perPage = null; + protected ?bool $useSquareDisplay = null; + public static function getDefaultName(): ?string { return 'unsplash_picker'; @@ -40,7 +40,7 @@ protected function setUp(): void $this->modalWidth(fn (MountableAction $action): ?MaxWidth => MaxWidth::ScreenLarge); - $this->modalContent(fn () => new HtmlString(Blade::render("@livewire('unsplash-picker-component', {$this->getOptions()})"))); + $this->modalContent(fn () => view('unsplash-picker::unsplash-picker', ['options' => $this->getOptions()])); $this->action($this->uploadImage(...)); } @@ -52,6 +52,13 @@ public function perPage(int $perPage): static return $this; } + public function useSquareDisplay(bool $useSquareDisplay): static + { + $this->useSquareDisplay = $useSquareDisplay; + + return $this; + } + public function raw(): static { $this->imageSize = ImageSize::Raw; @@ -125,15 +132,19 @@ public function getImageSize(): ImageSize public function getPerPage(): ?int { - return $this->perPage; + return $this->perPage ?? config('unsplash-picker.per_page'); } - public function getOptions() + public function shouldUseSquareDisplay(): ?bool { - if (! $this->getPerPage()) { - return; - } + return $this->useSquareDisplay ?? config('unsplash-picker.use_square_display'); + } - return "['perPage' => {$this->getPerPage()}]"; + public function getOptions(): array + { + return [ + 'perPage' => $this->getPerPage(), + 'useSquareDisplay' => $this->shouldUseSquareDisplay(), + ]; } } diff --git a/src/Components/UnsplashPickerComponent.php b/src/Components/UnsplashPickerComponent.php index d1a04cb..72a61c0 100644 --- a/src/Components/UnsplashPickerComponent.php +++ b/src/Components/UnsplashPickerComponent.php @@ -6,7 +6,9 @@ use Filament\Actions\Action; use Filament\Actions\Concerns\InteractsWithActions; use Filament\Actions\Contracts\HasActions; +use Filament\Forms\Components\Split; use Filament\Forms\Components\TextInput; +use Filament\Forms\Components\Toggle; use Filament\Forms\Concerns\InteractsWithForms; use Filament\Forms\Contracts\HasForms; use Filament\Forms\Form; @@ -22,7 +24,9 @@ class UnsplashPickerComponent extends Component implements HasActions, HasForms public string $search = ''; - public ?int $perPage = null; + public int $perPage; + + public bool $useSquareDisplay = true; public int $page = 1; @@ -31,13 +35,24 @@ class UnsplashPickerComponent extends Component implements HasActions, HasForms public function form(Form $form): Form { return $form + // ->columns(5) + // ->extraAttributes(['']) ->schema([ - TextInput::make('search') - ->live(debounce: 300) - ->hiddenLabel() - ->autocomplete(false) - ->autofocus() - ->placeholder(__('unsplash-picker::unsplash-picker.search_for_an_image')), + Split::make([ + TextInput::make('search') + ->live(debounce: 300) + ->hiddenLabel() + ->autocomplete(false) + ->autofocus() + ->grow() + ->placeholder(__('unsplash-picker::unsplash-picker.search_for_an_image')), + + Toggle::make('useSquareDisplay') + ->label(__('unsplash-picker::unsplash-picker.square_mode')) + ->default(fn () => dd($this->shouldUseSquareDisplay())) + ->reactive() + ->grow(false), + ])->extraAttributes(['class' => 'items-center']), ]); } @@ -98,11 +113,17 @@ public function getTotalPages(): int public function getPerPage(): int { - return $this->perPage ?? config('unsplash-picker.per_page'); + return $this->perPage; + } + + #[Computed] + public function shouldUseSquareDisplay(): bool + { + return $this->useSquareDisplay; } public function render() { - return view('unsplash-picker::unsplash-picker'); + return view('unsplash-picker::livewire.unsplash-picker'); } }