Skip to content

Commit 9a9500c

Browse files
committed
feat: thumbnails on select block
1 parent 0481bd0 commit 9a9500c

File tree

10 files changed

+10609
-5
lines changed

10 files changed

+10609
-5
lines changed

package-lock.json

Lines changed: 4336 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/dist/page-builder-plugin.css

Lines changed: 6077 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
@php
2+
$gridDirection = $getGridDirection() ?? 'column';
3+
$id = $getId();
4+
$isDisabled = $isDisabled();
5+
$statePath = $getStatePath();
6+
$options = $getOptions();
7+
$idSanitized = str_replace(['-', '.'], '_', $id);
8+
$hasNoCategories = count($options) === 1;
9+
@endphp
10+
11+
12+
<div class="flex items-start w-full justify-start">
13+
@if (!$hasNoCategories)
14+
<nav class="mr-4 flex sticky top-0 left-0 flex-col ">
15+
@foreach ($options as $category => $_)
16+
@continue(!$category)
17+
<button type="button" x-data="{
18+
scrollToBlockGroup() {
19+
const blockGroup = document.querySelector(
20+
@js('#' . $idSanitized . '-' . $category . '-header')
21+
);
22+
blockGroup.scrollIntoView({ behavior: 'smooth' });
23+
}
24+
}" @click="scrollToBlockGroup"
25+
class="
26+
rounded-md dark:hover:bg-white/10 p-2 transition-all
27+
">
28+
{{ $category }}
29+
</button>
30+
@endforeach
31+
</nav>
32+
@endif
33+
<div class="flex-col flex">
34+
@foreach ($options as $category => $categoryOptions)
35+
<section class="w-full">
36+
<h1 id="{{ $idSanitized . '-' . $category . '-header' }}" class="my-2">{{ $category }}</h1>
37+
<hr class="mb-2 dark:border-white/10 border-gray-200" />
38+
<x-filament::grid :default="$getColumns('default')" :sm="$getColumns('sm')" :md="$getColumns('md')" :lg="$getColumns('lg')"
39+
:xl="$getColumns('xl')" :two-xl="$getColumns('2xl')" :direction="$gridDirection" :attributes="\Filament\Support\prepare_inherited_attributes($attributes)
40+
->merge($getExtraAttributes(), escape: false)
41+
->class(['fi-fo-radio gap-4 w-full'])">
42+
@foreach ($categoryOptions as $value => $label)
43+
@php
44+
$thumbnail = $getBlockThumbnail($value);
45+
@endphp
46+
<div @class([
47+
'break-inside-avoid' => $gridDirection === 'column',
48+
])>
49+
<label for="{{ $id . '-' . $value }}" class="flex w-full h-full group">
50+
<x-filament::input.radio :valid="!$errors->has($statePath)" :attributes="\Filament\Support\prepare_inherited_attributes($getExtraInputAttributeBag())
51+
->merge(
52+
[
53+
'disabled' => $isDisabled || $isOptionDisabled($value, $label),
54+
'id' => $id . '-' . $value,
55+
'name' => $id,
56+
'value' => $value,
57+
'wire:loading.attr' => 'disabled',
58+
$applyStateBindingModifiers('wire:model') => $statePath,
59+
],
60+
escape: false,
61+
)
62+
->class(['peer hidden'])" />
63+
<div
64+
class="border-gray-200 cursor-pointer px-2 pb-2 peer-checked:bg-gray-100
65+
dark:peer-checked:bg-white/10 peer-checked:border-primary-500
66+
transition-all rounded-lg text-center border w-full bg-white
67+
dark:bg-gray-900 dark:border-white/10 dark:hover:bg-white/5 hover:bg-gray-50">
68+
<span
69+
class="text-sm font-medium leading-6 text-gray-950 dark:text-white">{{ $label }}</span>
70+
@if ((bool) $thumbnail)
71+
@if ($thumbnail instanceof \Illuminate\Contracts\Support\Htmlable)
72+
{!! $thumbnail !!}
73+
@else
74+
<img src="{{ $thumbnail }}" alt="{{ $label }}"
75+
class="w-full h-32 object-cover rounded-lg mt-2">
76+
@endif
77+
@endif
78+
</div>
79+
</label>
80+
</div>
81+
@endforeach
82+
</x-filament::grid>
83+
</section>
84+
@endforeach
85+
</div>
86+
</div>

src/Abstracts/BaseBlock.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Redberry\PageBuilderPlugin\Abstracts;
44

5+
use Illuminate\Contracts\Support\Htmlable;
56
use Illuminate\Support\Facades\Storage;
67
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
78

@@ -67,6 +68,16 @@ public static function getView(): ?string
6768
return null;
6869
}
6970

71+
public static function getThumbnail(): string|Htmlable|null
72+
{
73+
return null;
74+
}
75+
76+
public static function getIsSelectionDisabled(): bool
77+
{
78+
return false;
79+
}
80+
7081
public static function getBlockLabel(array $state, ?int $index = null): mixed
7182
{
7283
$key = static::getBlockTitleAttribute();

src/Components/Forms/Actions/SelectBlockAction.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
namespace Redberry\PageBuilderPlugin\Components\Forms\Actions;
44

5+
use Closure;
56
use Filament\Forms\Components\Actions\Action;
67
use Filament\Forms\Components\Select;
8+
use Filament\Support\Enums\MaxWidth;
79
use Redberry\PageBuilderPlugin\Components\Forms\PageBuilder;
10+
use Redberry\PageBuilderPlugin\Components\Forms\RadioButtonImage;
11+
use Redberry\PageBuilderPlugin\Traits\CanRenderWithThumbnails;
812

913
class SelectBlockAction extends Action
1014
{
15+
use CanRenderWithThumbnails;
16+
1117
public static function getDefaultName(): ?string
1218
{
1319
return 'select-page-builder-block';
@@ -21,20 +27,42 @@ protected function setUp(): void
2127

2228
$this->icon('heroicon-o-plus');
2329

30+
$this->modalWidth(MaxWidth::FiveExtraLarge);
31+
2432
$this->color('primary');
2533

2634
$this->form(function ($form, PageBuilder $component) {
35+
if ($this->getRenderWithThumbnails()) {
36+
return $form->schema([
37+
RadioButtonImage::make('block_type')
38+
->translateLabel()
39+
->disableOptionWhen(
40+
fn ($value) => (bool) $this->evaluate(Closure::fromCallable([$value, 'getIsSelectionDisabled']))
41+
)
42+
->required()
43+
->columns(3)
44+
->columnSpanFull()
45+
->options($this->formatBlocksForSelect($component))
46+
]);
47+
}
48+
49+
2750
return $form->schema([
2851
Select::make('block_type')
2952
->native(false)
3053
->translateLabel()
54+
->disableOptionWhen(
55+
fn ($value) => (bool) $this->evaluate(Closure::fromCallable([$value, 'getIsSelectionDisabled'])),
56+
)
3157
->required()
3258
->translateLabel()
3359
->options($this->formatBlocksForSelect($component)),
3460
]);
3561
});
3662

37-
$this->action(function ($data, $livewire, Action $action, PageBuilder $component) {
63+
$this->stickyModalFooter();
64+
65+
$this->action(function ($data, $livewire, PageBuilder $component) {
3866
$livewire->mountFormComponentAction(
3967
$component->getStatePath(),
4068
$component->getCreateActionName(),

src/Components/Forms/PageBuilder.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
use Redberry\PageBuilderPlugin\Components\Forms\Actions\EditPageBuilderBlockAction;
1818
use Redberry\PageBuilderPlugin\Components\Forms\Actions\ReorderPageBuilderBlockAction;
1919
use Redberry\PageBuilderPlugin\Components\Forms\Actions\SelectBlockAction;
20+
use Redberry\PageBuilderPlugin\Traits\CanRenderWithThumbnails;
2021
use Redberry\PageBuilderPlugin\Traits\ComponentLoadsPageBuilderBlocks;
2122
use Redberry\PageBuilderPlugin\Traits\FormatsBlockLabelWithContext;
2223

2324
class PageBuilder extends Field
2425
{
2526
use ComponentLoadsPageBuilderBlocks;
2627
use FormatsBlockLabelWithContext;
28+
use CanRenderWithThumbnails;
2729

2830
public bool | Closure $reorderable = false;
2931

@@ -96,6 +98,7 @@ public function getSelectBlockAction(): Action
9698
$action = SelectBlockAction::make($this->getSelectBlockActionName())
9799
->label('Add block')
98100
->translateLabel()
101+
->renderWithThumbnails($this->getRenderWithThumbnails())
99102
->disabled($this->isDisabled());
100103

101104
if ($this->modifySelectBlockActionUsing) {
@@ -366,7 +369,7 @@ public function relationship(
366369
->danger()
367370
->send();
368371

369-
throw new Halt;
372+
throw new Halt();
370373
}
371374

372375
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Redberry\PageBuilderPlugin\Components\Forms;
4+
5+
use Closure;
6+
use Filament\Forms\Components\Concerns\CanDisableOptions;
7+
use Filament\Forms\Components\Concerns\HasExtraInputAttributes;
8+
use Filament\Forms\Components\Concerns\HasGridDirection;
9+
use Filament\Forms\Components\Concerns\HasOptions;
10+
use Filament\Forms\Components\Field;
11+
use Illuminate\Contracts\Support\Htmlable;
12+
use Redberry\PageBuilderPlugin\Abstracts\BaseBlock;
13+
14+
class RadioButtonImage extends Field
15+
{
16+
use HasOptions;
17+
use CanDisableOptions;
18+
use HasGridDirection;
19+
use HasExtraInputAttributes;
20+
21+
public string $view = 'page-builder-plugin::forms.radio-button-image';
22+
23+
/**
24+
* Returns the thumbnail for the given block type.
25+
*
26+
* @param class-string<BaseBlock> $blockType
27+
* @return string|null
28+
*/
29+
public function getBlockThumbnail(string $blockType): string|Htmlable|null
30+
{
31+
$closure = Closure::fromCallable([$blockType, 'getThumbnail']);
32+
33+
return $this->evaluate($closure) ?? null;
34+
}
35+
}

src/PageBuilderPluginServiceProvider.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Redberry\PageBuilderPlugin;
44

55
use Filament\Support\Assets\Asset;
6+
use Filament\Support\Assets\Css;
67
use Filament\Support\Facades\FilamentAsset;
78
use Filament\Support\Facades\FilamentIcon;
89
use Illuminate\Filesystem\Filesystem;
@@ -50,7 +51,9 @@ public function configurePackage(Package $package): void
5051
}
5152
}
5253

53-
public function packageRegistered(): void {}
54+
public function packageRegistered(): void
55+
{
56+
}
5457

5558
public function packageBooted(): void
5659
{
@@ -78,7 +81,7 @@ public function packageBooted(): void
7881
}
7982

8083
// Testing
81-
Testable::mixin(new TestsPageBuilderPlugin);
84+
Testable::mixin(new TestsPageBuilderPlugin());
8285
}
8386

8487
protected function getAssetPackageName(): ?string
@@ -92,6 +95,7 @@ protected function getAssetPackageName(): ?string
9295
protected function getAssets(): array
9396
{
9497
return [
98+
Css::make('page-builder-plugin-styles', __DIR__ . '/../resources/dist/page-builder-plugin.css'),
9599
];
96100
}
97101

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Redberry\PageBuilderPlugin\Traits;
4+
5+
use Closure;
6+
7+
8+
trait CanRenderWithThumbnails
9+
{
10+
protected bool | Closure $renderWithThumbnails = false;
11+
12+
public function renderWithThumbnails(
13+
bool | Closure $renderWithThumbnails = true,
14+
) {
15+
$this->renderWithThumbnails = $renderWithThumbnails;
16+
17+
return $this;
18+
}
19+
20+
public function getRenderWithThumbnails(): bool
21+
{
22+
return (bool) $this->evaluate($this->renderWithThumbnails);
23+
}
24+
}

tailwind.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module.exports = {
44
presets: [preset],
55
content: [
66
'./app/Filament/**/*.php',
7-
'./resources/views/filament/**/*.blade.php',
7+
'./resources/views/**/*.blade.php',
88
'./vendor/filament/**/*.blade.php',
99
],
1010
}

0 commit comments

Comments
 (0)