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