diff --git a/packages/notifications/docs/01-installation.md b/packages/notifications/docs/01-installation.md index 8ede4d56ec..0be815cb0b 100644 --- a/packages/notifications/docs/01-installation.md +++ b/packages/notifications/docs/01-installation.md @@ -39,6 +39,7 @@ You're now ready to start [sending notifications](sending-notifications)! The package uses the following dependencies: - [Alpine.js](https://alpinejs.dev) +- [Alpine Floating UI](https://github.com/awcodes/alpine-floating-ui) - [Tailwind CSS](https://tailwindcss.com) You may install these through NPM: @@ -146,12 +147,14 @@ In `/resources/css/app.css`, import [Tailwind CSS](https://tailwindcss.com): ### Configuring scripts -In `/resources/js/app.js`, import [Alpine.js](https://alpinejs.dev) and the `filament/notifications` plugin, and register it: +In `/resources/js/app.js`, import [Alpine.js](https://alpinejs.dev), Alpine Floating UI and the `filament/notifications` plugin, and register them: ```js import Alpine from 'alpinejs' +import AlpineFloatingUI from '@awcodes/alpine-floating-ui' import NotificationsAlpinePlugin from '../../vendor/filament/notifications/dist/module.esm' +Alpine.plugin(AlpineFloatingUI) Alpine.plugin(NotificationsAlpinePlugin) window.Alpine = Alpine diff --git a/packages/notifications/resources/views/actions/group.blade.php b/packages/notifications/resources/views/actions/group.blade.php new file mode 100644 index 0000000000..04b3357a9c --- /dev/null +++ b/packages/notifications/resources/views/actions/group.blade.php @@ -0,0 +1,8 @@ + diff --git a/packages/notifications/resources/views/actions/grouped-action.blade.php b/packages/notifications/resources/views/actions/grouped-action.blade.php new file mode 100644 index 0000000000..2561ee3030 --- /dev/null +++ b/packages/notifications/resources/views/actions/grouped-action.blade.php @@ -0,0 +1,8 @@ + + {{ $getLabel() }} + diff --git a/packages/notifications/resources/views/components/dropdown/item.blade.php b/packages/notifications/resources/views/components/dropdown/item.blade.php new file mode 100644 index 0000000000..4ba3924180 --- /dev/null +++ b/packages/notifications/resources/views/components/dropdown/item.blade.php @@ -0,0 +1,10 @@ +@captureSlots([ + 'detail', +]) + + + {{ $slot }} + diff --git a/packages/notifications/src/Actions/Action.php b/packages/notifications/src/Actions/Action.php index ff72976bf2..467c93a644 100644 --- a/packages/notifications/src/Actions/Action.php +++ b/packages/notifications/src/Actions/Action.php @@ -77,6 +77,13 @@ class Action extends BaseAction implements Arrayable return $this; } + public function grouped(): static + { + $this->view('notifications::actions.grouped-action'); + + return $this; + } + public function link(): static { $this->view('notifications::actions.link-action'); diff --git a/packages/notifications/src/Actions/ActionGroup.php b/packages/notifications/src/Actions/ActionGroup.php new file mode 100644 index 0000000000..0ae87fec46 --- /dev/null +++ b/packages/notifications/src/Actions/ActionGroup.php @@ -0,0 +1,41 @@ + collect($this->getActions())->toArray(), + 'color' => $this->getColor(), + 'icon' => $this->getIcon(), + 'iconPosition' => $this->getIconPosition(), + 'label' => $this->getLabel(), + 'tooltip' => $this->getTooltip(), + ]; + } + + public static function fromArray(array $data): static + { + $static = static::make( + array_map( + fn (array $action): Action => Action::fromArray($action), + $data['actions'], + ), + ); + + $static->color($data['color']); + $static->icon($data['icon']); + $static->iconPosition($data['iconPosition']); + $static->label($data['label']); + $static->tooltip($data['tooltip']); + + return $static; + } +} diff --git a/packages/notifications/src/Concerns/HasActions.php b/packages/notifications/src/Concerns/HasActions.php index d4e055757c..963c26a35e 100644 --- a/packages/notifications/src/Concerns/HasActions.php +++ b/packages/notifications/src/Concerns/HasActions.php @@ -3,12 +3,14 @@ namespace Filament\Notifications\Concerns; use Closure; +use Filament\Notifications\Actions\ActionGroup; +use Illuminate\Support\Arr; trait HasActions { - protected array | Closure $actions = []; + protected array | ActionGroup | Closure $actions = []; - public function actions(array | Closure $actions): static + public function actions(array | ActionGroup | Closure $actions): static { $this->actions = $actions; @@ -17,6 +19,6 @@ trait HasActions public function getActions(): array { - return $this->evaluate($this->actions); + return Arr::wrap($this->evaluate($this->actions)); } } diff --git a/packages/notifications/src/Notification.php b/packages/notifications/src/Notification.php index d1e6a9c833..947ab433d2 100644 --- a/packages/notifications/src/Notification.php +++ b/packages/notifications/src/Notification.php @@ -3,6 +3,7 @@ namespace Filament\Notifications; use Filament\Notifications\Actions\Action; +use Filament\Notifications\Actions\ActionGroup; use Filament\Notifications\Concerns\HasActions; use Filament\Notifications\Concerns\HasBody; use Filament\Notifications\Concerns\HasDuration; @@ -43,7 +44,7 @@ class Notification extends ViewComponent implements Arrayable { return [ 'id' => $this->getId(), - 'actions' => collect($this->getActions())->toArray(), + 'actions' => array_map(fn (Action | ActionGroup $action): array => $action->toArray(), $this->getActions()), 'body' => $this->getBody(), 'duration' => $this->getDuration(), 'icon' => $this->getIcon(), @@ -55,7 +56,15 @@ class Notification extends ViewComponent implements Arrayable public static function fromArray(array $data): static { $static = static::make($data['id']); - $static->actions(array_map(fn (array $action): Action => Action::fromArray($action), $data['actions'])); + $static->actions( + array_map( + fn (array $action): Action | ActionGroup => match (array_key_exists('actions', $action)) { + true => ActionGroup::fromArray($action), + false => Action::fromArray($action), + }, + $data['actions'], + ), + ); $static->body($data['body']); $static->duration($data['duration']); $static->icon($data['icon']); diff --git a/packages/notifications/stubs/scaffolding/resources/js/app.js b/packages/notifications/stubs/scaffolding/resources/js/app.js index e9e70c18d4..11d41c9089 100644 --- a/packages/notifications/stubs/scaffolding/resources/js/app.js +++ b/packages/notifications/stubs/scaffolding/resources/js/app.js @@ -1,6 +1,8 @@ import Alpine from 'alpinejs' +import AlpineFloatingUI from '@awcodes/alpine-floating-ui' import NotificationsAlpinePlugin from '../../vendor/filament/notifications/dist/module.esm' +Alpine.plugin(AlpineFloatingUI) Alpine.plugin(NotificationsAlpinePlugin) window.Alpine = Alpine