Skip to content

Commit 74c35e2

Browse files
authored
Add Action Buttons (rappasoft#1864)
* Make ActionButtons An Optional Feature in Beta --------- Co-authored-by: lrljoe <[email protected]>
1 parent 1ff4126 commit 74c35e2

File tree

16 files changed

+881
-1
lines changed

16 files changed

+881
-1
lines changed

docs/misc/actions.md

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
---
2+
title: Actions (beta)
3+
weight: 4
4+
---
5+
6+
Actions is a beta feature, that allows for the creation of Action Buttons that appear above the toolbar. These are ideal for common Actions that do not impact existing records, such as a "Create", "Assign", "Back" buttons.
7+
8+
This is NOT recommended for production use at this point in time.
9+
10+
## Usage
11+
To use "Actions", while it is in beta, you must include the following Trait in your table:
12+
```php
13+
use Rappasoft\LaravelLivewireTables\Traits\WithActions;
14+
```
15+
16+
Once out of beta, this will not be required.
17+
18+
## Component Available Methods
19+
### setActionWrapperAttributes
20+
21+
This is used to set attributes for the "div" that wraps all defined Action Buttons:
22+
23+
```php
24+
public function configure(): void
25+
{
26+
$this->setActionWrapperAttributes([
27+
'class' => 'space-x-4'
28+
]);
29+
}
30+
```
31+
32+
### actions()
33+
34+
Define your actions using the actions() method:
35+
36+
```php
37+
public function actions(): array
38+
{
39+
return [
40+
Action::make('View Dashboard')
41+
->setRoute('dashboard'),
42+
];
43+
}
44+
```
45+
46+
## Button Available Methods
47+
48+
### setActionAttributes
49+
50+
setActionAttributes is used to pass any attributes that you wish to implement on the "button" element for the action button. By default it will merge with the default classes.
51+
52+
You can set "default-styling" and "default-colors" to false to replace, rather than over-ride either default-styling or default-colors.
53+
```php
54+
public function actions(): array
55+
{
56+
return [
57+
Action::make('View Dashboard')
58+
->setActionAttributes([
59+
'class' => 'dark:bg-blue-500 dark:text-white dark:border-blue-600 dark:hover:border-blue-900 dark:hover:bg-blue-800',
60+
'default-colors' => false, // Will over-ride the default colors
61+
'default-styling' => true // Will use the default styling
62+
]),
63+
];
64+
}
65+
```
66+
67+
### setIcon
68+
69+
setIcon is used to set an icon for the action button
70+
71+
```php
72+
public function actions(): array
73+
{
74+
return [
75+
Action::make('Edit Item')
76+
->setIcon("fas fa-edit"),
77+
];
78+
}
79+
```
80+
81+
### setIconAttributes
82+
83+
setIconAttributes is used to set any additional attributes for the Icon for the action button
84+
```php
85+
public function actions(): array
86+
{
87+
return [
88+
Action::make('Edit Item')
89+
->setIcon("fas fa-edit")
90+
->setIconAttributes(['class' => 'font-4xl text-4xl']),
91+
];
92+
}
93+
```
94+
95+
### setRoute
96+
97+
Used for non-wireable butons, to set the route that the action button should take the user to upon clicking.
98+
```php
99+
public function actions(): array
100+
{
101+
return [
102+
Action::make('Dashboard')
103+
->setRoute('dashboard')
104+
];
105+
}
106+
```
107+
108+
### wireNavigate
109+
110+
Used in conjunction with setRoute - makes the link "wire:navigate" rather than default behaviour
111+
```php
112+
public function actions(): array
113+
{
114+
return [
115+
Action::make('Dashboard')
116+
->setRoute('dashboard')
117+
->wireNavigate()
118+
];
119+
}
120+
```
121+
122+
### setWireAction
123+
```php
124+
public function actions(): array
125+
{
126+
return [
127+
Action::make('Create 2')
128+
->setWireAction("wire:click")
129+
];
130+
}
131+
```
132+
133+
### setWireActionParams
134+
Specify the action & parameters to pass to the wire:click method
135+
136+
```php
137+
public function actions(): array
138+
{
139+
return [
140+
Action::make('Create 2')
141+
->setWireAction("wire:click")
142+
->setWireActionParams(['id' => 'test']),
143+
];
144+
}
145+
```
146+
147+
### setWireActionDispatchParams
148+
149+
Use $dispatch rather than a typical wire:click action
150+
151+
```php
152+
public function actions(): array
153+
{
154+
return [
155+
Action::make('Create 2')
156+
->setWireAction("wire:click")
157+
->setWireActionDispatchParams("'openModal', { component: 'test-modal' }"),
158+
];
159+
}
160+
```
161+
162+
### setView
163+
164+
This is used to set a Custom View for the Button
165+
166+
```php
167+
public function actions(): array
168+
{
169+
return [
170+
Action::make('Edit Item')
171+
->setView("buttons.edit"),
172+
];
173+
}
174+
```
175+
176+
## Extending
177+
178+
You can extend the Base Action class which can be a useful timesaver, when you wish to re-use the same look/feel of an Action, but wish to set a different route (for example).
179+
You can set any defaults in the __construct method, ensuring that the parent constructor is called first!
180+
181+
```php
182+
use Rappasoft\LaravelLivewireTables\Views\Action;
183+
184+
class EditAction extends Action
185+
{
186+
public function __construct(?string $label = null)
187+
{
188+
parent::__construct($label);
189+
$this
190+
->setActionAttributes([
191+
'class' => 'dark:bg-blue-500 dark:text-white dark:border-blue-600 dark:hover:border-blue-900 dark:hover:bg-blue-800',
192+
'default-colors' => false,
193+
'default-styling' => true
194+
])
195+
->setIcon("fas fa-edit")
196+
->setIconAttributes([
197+
'class' => 'font-4xl text-4xl'
198+
]);
199+
}
200+
}
201+
```
202+
203+
You may define a Custom View to be used via either the setView method, or by defining the view directly in your class.
204+
```php
205+
protected string $view = 'buttons.edit-action';
206+
```
207+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div {{ $attributes
2+
->merge($this->getActionWrapperAttributes())
3+
->class(['flex flex-cols justify-center' => $this->isTailwind && $this->getActionWrapperAttributes()['default-styling'] ?? true])
4+
->class(['' => $this->isTailwind && $this->getActionWrapperAttributes()['default-colors'] ?? true])
5+
->class(['d-flex flex-cols justify-center' => $this->isBootstrap && $this->getActionWrapperAttributes()['default-styling'] ?? true])
6+
->class(['' => $this->isBootstrap && $this->getActionWrapperAttributes()['default-colors'] ?? true])
7+
->except(['default-styling','default-colors'])
8+
}} >
9+
@foreach($this->getActions as $action)
10+
{{ $action->render() }}
11+
@endforeach
12+
</div>

resources/views/datatable.blade.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88

99
<div x-data="laravellivewiretable($wire, '{{ $this->showBulkActionsDropdownAlpine() }}', '{{ $tableId }}', '{{ $primaryKey }}')">
1010
<x-livewire-tables::wrapper :component="$this" :tableName="$tableName" :$primaryKey :$isTailwind :$isBootstrap :$isBootstrap4 :$isBootstrap5>
11+
@if(method_exists($this,'hasActions') && $this->hasActions())
12+
<x-livewire-tables::includes.actions/>
13+
@endif
14+
15+
1116
@if ($this->hasConfigurableAreaFor('before-tools'))
1217
@include($this->getConfigurableAreaFor('before-tools'), $this->getParametersForConfigurableArea('before-tools'))
1318
@endif
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<a {{ $attributes->merge()
2+
->class(['justify-center text-center items-center inline-flex rounded-md border shadow-sm px-4 py-2 text-sm font-medium focus:ring focus:ring-opacity-50' => $isTailwind && $attributes['default-styling'] ?? true])
3+
->class(['focus:border-indigo-300 focus:ring-indigo-200' => $isTailwind && $attributes['default-colors'] ?? true])
4+
->class(['btn btn-sm btn-success' => $isBootstrap && $attributes['default-styling'] ?? true])
5+
->class(['' => $isBootstrap && $attributes['default-colors'] ?? true])
6+
->except(['default-styling', 'default-colors'])
7+
}}
8+
@if($action->hasWireAction())
9+
{{ $action->getWireAction() }}="{{ $action->getWireActionParams() }}"
10+
@endif
11+
@if($action->getWireNavigateEnabled())
12+
wire:navigate
13+
@endif
14+
>
15+
{{ $action->getLabel() }}
16+
17+
@if($action->hasIcon())
18+
<i {{ $action->getIconAttributes()
19+
->class(["ms-1 ". $action->getIcon() => $isBootstrap])
20+
->class(["ml-1 ". $action->getIcon() => $isTailwind])
21+
->except('default-styling')
22+
}}></i>
23+
@endif
24+
</a>

src/Traits/HasAllTraits.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ trait HasAllTraits
88
use WithTableHooks;
99
use WithLoadingPlaceholder;
1010
use ComponentUtilities,
11+
//WithActions,
1112
WithData,
1213
WithColumns,
1314
WithSorting,

src/Traits/WithActions.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Traits;
4+
5+
use Illuminate\Support\Collection;
6+
use Livewire\Attributes\Computed;
7+
use Rappasoft\LaravelLivewireTables\Views\Action;
8+
9+
trait WithActions
10+
{
11+
protected array $actionWrapperAttributes = ['default-styling' => true, 'default-colors' => true];
12+
13+
protected function actions(): array
14+
{
15+
return [];
16+
}
17+
18+
public function setActionWrapperAttributes(array $actionWrapperAttributes): self
19+
{
20+
$this->actionWrapperAttributes = [...['default-styling' => true, 'default-colors' => true], ...$actionWrapperAttributes];
21+
22+
return $this;
23+
}
24+
25+
#[Computed]
26+
public function getActionWrapperAttributes(): array
27+
{
28+
return [...['default-styling' => true, 'default-colors' => true], ...$this->actionWrapperAttributes];
29+
}
30+
31+
#[Computed]
32+
public function hasActions(): bool
33+
{
34+
return (new Collection($this->actions()))
35+
->filter(fn ($action) => $action instanceof Action)->count() > 0;
36+
}
37+
38+
#[Computed]
39+
public function getActions(): Collection
40+
{
41+
return (new Collection($this->actions()))
42+
->filter(fn ($action) => $action instanceof Action)
43+
->each(function (Action $action, int $key) {
44+
$action->setTheme($this->getTheme());
45+
});
46+
47+
}
48+
}

src/Views/Action.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views;
4+
5+
use Illuminate\View\Component;
6+
use Illuminate\View\ComponentAttributeBag;
7+
use Rappasoft\LaravelLivewireTables\Views\Traits\Actions\{HasActionAttributes, HasRoute};
8+
use Rappasoft\LaravelLivewireTables\Views\Traits\Columns\HasVisibility;
9+
use Rappasoft\LaravelLivewireTables\Views\Traits\Core\{HasIcon, HasLabel, HasTheme, HasView, HasWireActions};
10+
11+
class Action extends Component
12+
{
13+
use HasActionAttributes;
14+
use HasIcon;
15+
use HasLabel;
16+
use HasRoute;
17+
use HasTheme;
18+
use HasView;
19+
use HasVisibility;
20+
use HasWireActions;
21+
22+
protected string $view = 'livewire-tables::includes.actions.button';
23+
24+
public function __construct(?string $label = null)
25+
{
26+
$this->label = trim(__($label));
27+
}
28+
29+
public static function make(?string $label = null): self
30+
{
31+
return new static($label);
32+
}
33+
34+
public function render(): null|string|\Illuminate\Support\HtmlString|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
35+
{
36+
$view = view($this->getView())
37+
->withAction($this)
38+
->withIsBootstrap($this->isBootstrap())
39+
->withIsTailwind($this->isTailwind())
40+
->withAttributes($this->getActionAttributes());
41+
42+
return $view;
43+
}
44+
}

src/Views/Actions/Action.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views\Actions;
4+
5+
use Rappasoft\LaravelLivewireTables\Views\Action as BaseAction;
6+
7+
class Action extends BaseAction
8+
{
9+
public function __construct(?string $label = null)
10+
{
11+
parent::__construct($label);
12+
}
13+
}

0 commit comments

Comments
 (0)