From 733e5594ffaf9340e07901f83e696aab192375b4 Mon Sep 17 00:00:00 2001 From: ZedoX <75579178+Z3d0X@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:31:46 +0500 Subject: [PATCH] [Feat]: Block Picker Styles (#136) * wip * fix modal style * Fix styling * ui fix * docs --------- Co-authored-by: Z3d0X --- docs/README.md | 39 +++ .../forms/components/page-builder.blade.php | 282 ++++++++++++++++++ .../dropdown-block-picker.blade.php | 52 ++++ .../page-builder/modal-block-picker.blade.php | 63 ++++ src/Enums/BlockPickerStyle.php | 9 + src/FilamentFabricatorPlugin.php | 24 ++ src/Forms/Components/PageBuilder.php | 28 ++ 7 files changed, 497 insertions(+) create mode 100644 resources/views/components/forms/components/page-builder.blade.php create mode 100644 resources/views/components/forms/components/page-builder/dropdown-block-picker.blade.php create mode 100644 resources/views/components/forms/components/page-builder/modal-block-picker.blade.php create mode 100644 src/Enums/BlockPickerStyle.php diff --git a/docs/README.md b/docs/README.md index 836be8a..4caa8a1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -222,6 +222,45 @@ PageBuilder::configureUsing(function (PageBuilder $builder) { }); ``` +### Block Picker Styles + +In addition to [customizations available in Filament's Builder](https://filamentphp.com/docs/3.x/forms/fields/builder#customizing-the-block-picker) `PageBuilder`, also includes a new method `blockPickerStyle()`. +Currently there are two styles available: +- `BlockPickerStyle::Dropdown` (default) +- `BlockPickerStyle::Modal` + + +```php +use Z3d0X\FilamentFabricator\Enums\BlockPickerStyle; +use Z3d0X\FilamentFabricator\Forms\Components\PageBuilder; + +PageBuilder::configureUsing(function (PageBuilder $builder) { + $builder->blockPickerStyle(BlockPickerStyle::Modal); +}); +``` + +an alternative one-liner way of changing block picker style is using `blockPickerStyle()` method when registering the `FilamentFabricatorPlugin` in your Panel provider: + +```php +use Z3d0X\FilamentFabricator\Enums\BlockPickerStyle; +use Z3d0X\FilamentFabricator\FilamentFabricatorPlugin; + +//.. + +public function panel(Panel $panel): Panel +{ + return $panel + // ... + ->plugins([ + FilamentFabricatorPlugin::make() + ->blockPickerStyle(BlockPickerStyle::Modal), + ]); +} +``` + +> Pro Tip 💡: `BlockPickerStyle::Modal` works best when icons are assigned to blocks. https://filamentphp.com/docs/3.x/forms/fields/builder#setting-a-blocks-icon + + ## Page Resource ### Customize Navigation diff --git a/resources/views/components/forms/components/page-builder.blade.php b/resources/views/components/forms/components/page-builder.blade.php new file mode 100644 index 0000000..82bd143 --- /dev/null +++ b/resources/views/components/forms/components/page-builder.blade.php @@ -0,0 +1,282 @@ +@php + use Filament\Forms\Components\Actions\Action; + use Z3d0X\FilamentFabricator\Enums\BlockPickerStyle; + + $containers = $getChildComponentContainers(); + $blockPickerBlocks = $getBlockPickerBlocks(); + $blockPickerColumns = $getBlockPickerColumns(); + $blockPickerWidth = $getBlockPickerWidth(); + $blockPickerStyle = $getBlockPickerStyle(); + + $addAction = $getAction($getAddActionName()); + $addBetweenAction = $getAction($getAddBetweenActionName()); + $cloneAction = $getAction($getCloneActionName()); + $collapseAllAction = $getAction($getCollapseAllActionName()); + $expandAllAction = $getAction($getExpandAllActionName()); + $deleteAction = $getAction($getDeleteActionName()); + $moveDownAction = $getAction($getMoveDownActionName()); + $moveUpAction = $getAction($getMoveUpActionName()); + $reorderAction = $getAction($getReorderActionName()); + $extraItemActions = $getExtraItemActions(); + + $isAddable = $isAddable(); + $isCloneable = $isCloneable(); + $isCollapsible = $isCollapsible(); + $isDeletable = $isDeletable(); + $isReorderableWithButtons = $isReorderableWithButtons(); + $isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop(); + + $statePath = $getStatePath(); +@endphp + + +
merge($getExtraAttributes(), escape: false) + ->class(['fi-fo-builder grid gap-y-4']) + }} + > + @if ($isCollapsible && ($collapseAllAction->isVisible() || $expandAllAction->isVisible())) +
count($containers) < 2, + ]) + > + @if ($collapseAllAction->isVisible()) + + {{ $collapseAllAction }} + + @endif + + @if ($expandAllAction->isVisible()) + + {{ $expandAllAction }} + + @endif +
+ @endif + + @if (count($containers)) +
    + @php + $hasBlockLabels = $hasBlockLabels(); + $hasBlockNumbers = $hasBlockNumbers(); + @endphp + + @foreach ($containers as $uuid => $item) + @php + $visibleExtraItemActions = array_filter( + $extraItemActions, + fn (Action $action): bool => $action(['item' => $uuid])->isVisible(), + ); + @endphp + +
  • + @if ($isReorderableWithDragAndDrop || $isReorderableWithButtons || $hasBlockLabels || $isCloneable || $isDeletable || $isCollapsible || count($visibleExtraItemActions)) +
    + @if ($isReorderableWithDragAndDrop || $isReorderableWithButtons) +
      + @if ($isReorderableWithDragAndDrop) +
    • + {{ $reorderAction }} +
    • + @endif + + @if ($isReorderableWithButtons) +
    • + {{ $moveUpAction(['item' => $uuid])->disabled($loop->first) }} +
    • + +
    • + {{ $moveDownAction(['item' => $uuid])->disabled($loop->last) }} +
    • + @endif +
    + @endif + + @if ($hasBlockLabels) +

    $isBlockLabelTruncated(), + 'cursor-pointer select-none' => $isCollapsible, + ]) + > + {{ $item->getParentComponent()->getLabel($item->getRawState(), $uuid) }} + + @if ($hasBlockNumbers) + {{ $loop->iteration }} + @endif +

    + @endif + + @if ($isCloneable || $isDeletable || $isCollapsible || count($visibleExtraItemActions)) +
      + @foreach ($visibleExtraItemActions as $extraItemAction) +
    • + {{ $extraItemAction(['item' => $uuid]) }} +
    • + @endforeach + + @if ($isCloneable) +
    • + {{ $cloneAction(['item' => $uuid]) }} +
    • + @endif + + @if ($isDeletable) +
    • + {{ $deleteAction(['item' => $uuid]) }} +
    • + @endif + + @if ($isCollapsible) +
    • +
      + {{ $getAction('collapse') }} +
      + +
      + {{ $getAction('expand') }} +
      +
    • + @endif +
    + @endif +
    + @endif + +
    + {{ $item }} +
    +
  • + + @if (! $loop->last) + @if ($isAddable && $addBetweenAction->isVisible()) + + @elseif (filled($labelBetweenItems = $getLabelBetweenItems())) +
  • + + {{ $labelBetweenItems }} + +
  • + @endif + @endif + @endforeach +
+ @endif + + @if ($isAddable) + @if ($blockPickerStyle === BlockPickerStyle::Dropdown) + + + {{ $addAction }} + + + @elseif ($blockPickerStyle === BlockPickerStyle::Modal) + + + {{ $addAction }} + + + @endif + @endif +
+
diff --git a/resources/views/components/forms/components/page-builder/dropdown-block-picker.blade.php b/resources/views/components/forms/components/page-builder/dropdown-block-picker.blade.php new file mode 100644 index 0000000..a1a5c04 --- /dev/null +++ b/resources/views/components/forms/components/page-builder/dropdown-block-picker.blade.php @@ -0,0 +1,52 @@ +@props([ + 'action', + 'afterItem' => null, + 'blocks', + 'columns' => null, + 'statePath', + 'trigger', + 'width' => null, +]) + +class(['fi-fo-builder-block-picker']) }} +> + + {{ $trigger }} + + + + + @foreach ($blocks as $block) + @php + $wireClickActionArguments = ['block' => $block->getName()]; + + if ($afterItem) { + $wireClickActionArguments['afterItem'] = $afterItem; + } + + $wireClickActionArguments = \Illuminate\Support\Js::from($wireClickActionArguments); + + $wireClickAction = "mountFormComponentAction('{$statePath}', '{$action->getName()}', {$wireClickActionArguments})"; + @endphp + + + {{ $block->getLabel() }} + + @endforeach + + + diff --git a/resources/views/components/forms/components/page-builder/modal-block-picker.blade.php b/resources/views/components/forms/components/page-builder/modal-block-picker.blade.php new file mode 100644 index 0000000..b535b5e --- /dev/null +++ b/resources/views/components/forms/components/page-builder/modal-block-picker.blade.php @@ -0,0 +1,63 @@ +@props([ + 'action', + 'afterItem' => null, + 'blocks', + 'columns' => null, + 'statePath', + 'trigger', + 'width' => null, +]) + +class(['fi-fo-builder-block-picker']) }} +> + +
+ {{ $trigger }} +
+
+ + + @foreach ($blocks as $block) + @php + $wireClickActionArguments = ['block' => $block->getName()]; + + if ($afterItem) { + $wireClickActionArguments['afterItem'] = $afterItem; + } + + $wireClickActionArguments = \Illuminate\Support\Js::from($wireClickActionArguments); + + $wireClickAction = "mountFormComponentAction('{$statePath}', '{$action->getName()}', {$wireClickActionArguments})"; + @endphp + + + + @endforeach + +
+ diff --git a/src/Enums/BlockPickerStyle.php b/src/Enums/BlockPickerStyle.php new file mode 100644 index 0000000..e100af4 --- /dev/null +++ b/src/Enums/BlockPickerStyle.php @@ -0,0 +1,9 @@ +blockPickerStyle = $style; + + return $this; + } + + public function getBlockPickerStyle(): ?BlockPickerStyle + { + return $this->blockPickerStyle; + } + + public static function get(): static + { + /** @var static $plugin */ + $plugin = filament(app(static::class)->getId()); + + return $plugin; + } } diff --git a/src/Forms/Components/PageBuilder.php b/src/Forms/Components/PageBuilder.php index d0ad35d..58ba879 100644 --- a/src/Forms/Components/PageBuilder.php +++ b/src/Forms/Components/PageBuilder.php @@ -3,10 +3,16 @@ namespace Z3d0X\FilamentFabricator\Forms\Components; use Filament\Forms\Components\Builder; +use Z3d0X\FilamentFabricator\Enums\BlockPickerStyle; use Z3d0X\FilamentFabricator\Facades\FilamentFabricator; +use Z3d0X\FilamentFabricator\FilamentFabricatorPlugin; class PageBuilder extends Builder { + protected string $view = 'filament-fabricator::components.forms.components.page-builder'; + + protected BlockPickerStyle $blockPickerStyle = BlockPickerStyle::Dropdown; + protected function setUp(): void { parent::setUp(); @@ -25,5 +31,27 @@ protected function setUp(): void ->values() ->toArray(); }); + + $blockPickerStyle = FilamentFabricatorPlugin::get()->getBlockPickerStyle(); + + if (! is_null($blockPickerStyle)) { + $this->blockPickerStyle($blockPickerStyle); + } + } + + public function blockPickerStyle(BlockPickerStyle $style): static + { + if ($style === BlockPickerStyle::Modal) { + $this->blockPickerColumns(3); + } + + $this->blockPickerStyle = $style; + + return $this; + } + + public function getBlockPickerStyle(): BlockPickerStyle + { + return $this->blockPickerStyle; } }