diff --git a/CHANGELOG.md b/CHANGELOG.md
index d137430cf..23aceebc7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
All notable changes to `laravel-livewire-tables` will be documented in this file
+## [v3.2.1] - 2023-02-19
+### New Features
+- Creation of new WireLink Column
+
## [v3.2.0] - 2023-01-04
### Tweaks
- Migration to new Core Traits, and de-duplication of code by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/1623
diff --git a/docs/columns/other-column-types.md b/docs/columns/other-column-types.md
index dc80da449..0d15ab564 100644
--- a/docs/columns/other-column-types.md
+++ b/docs/columns/other-column-types.md
@@ -191,6 +191,41 @@ LinkColumn::make('Action')
]),
```
+## WireLinkColumn Columns
+
+WireLink columns provide a way to display Wired Links in your table without having to use `format()` or partial views, with or without a Confirmation Message
+
+WireLinkColumn requires title, and an "action", which must be a valid LiveWire method in the current class, or a global method
+
+Without a Confirmation Message
+```php
+ WireLinkColumn::make("Delete Item")
+ ->title(fn($row) => 'Delete Item')
+ ->action(fn($row) => 'delete("'.$row->id.'")'),
+```
+
+You may also pass a string to "confirmMessage", which will utilise LiveWire 3's "wire:confirm" approach to display a confirmation modal.
+
+```php
+ WireLinkColumn::make("Delete Item")
+ ->title(fn($row) => 'Delete Item')
+ ->confirmMessage('Are you sure you want to delete this item?')
+ ->action(fn($row) => 'delete("'.$row->id.'")')
+ ->attributes(fn($row) => [
+ 'class' => 'btn btn-danger',
+ ]),
+```
+
+And you may also pass an array of attributes, which will be applied to the "button" element used within the Column
+```php
+ WireLinkColumn::make("Delete Item")
+ ->title(fn($row) => 'Delete Item')
+ ->action(fn($row) => 'delete("'.$row->id.'")')
+ ->attributes(fn($row) => [
+ 'class' => 'btn btn-danger',
+ ]),
+```
+
## Button Group Columns
Button group columns let you provide an array of LinkColumns to display in a single cell.
diff --git a/resources/views/includes/columns/wirelink.blade.php b/resources/views/includes/columns/wirelink.blade.php
new file mode 100644
index 000000000..191ba5f1d
--- /dev/null
+++ b/resources/views/includes/columns/wirelink.blade.php
@@ -0,0 +1,9 @@
+
diff --git a/src/Traits/Helpers/TableAttributeHelpers.php b/src/Traits/Helpers/TableAttributeHelpers.php
index 25a970628..3da2da12e 100644
--- a/src/Traits/Helpers/TableAttributeHelpers.php
+++ b/src/Traits/Helpers/TableAttributeHelpers.php
@@ -16,7 +16,7 @@ public function getComponentWrapperAttributes(): array
}
/**
- * @return array
+ * @return array
*/
public function getTableWrapperAttributes(): array
{
@@ -24,7 +24,7 @@ public function getTableWrapperAttributes(): array
}
/**
- * @return array
+ * @return array
*/
public function getTableAttributes(): array
{
@@ -32,7 +32,7 @@ public function getTableAttributes(): array
}
/**
- * @return array
+ * @return array
*/
public function getTheadAttributes(): array
{
@@ -40,7 +40,7 @@ public function getTheadAttributes(): array
}
/**
- * @return array
+ * @return array
*/
public function getTbodyAttributes(): array
{
@@ -48,7 +48,7 @@ public function getTbodyAttributes(): array
}
/**
- * @return array
+ * @return array
*/
public function getThAttributes(Column $column): array
{
@@ -56,7 +56,7 @@ public function getThAttributes(Column $column): array
}
/**
- * @return array
+ * @return array
*/
public function getThSortButtonAttributes(Column $column): array
{
diff --git a/src/Views/Columns/WireLinkColumn.php b/src/Views/Columns/WireLinkColumn.php
new file mode 100644
index 000000000..91665f288
--- /dev/null
+++ b/src/Views/Columns/WireLinkColumn.php
@@ -0,0 +1,45 @@
+label(fn () => null);
+ }
+
+ public function getContents(Model $row): null|string|\Illuminate\Support\HtmlString|DataTableConfigurationException|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
+ {
+ if (! $this->hasTitleCallback()) {
+ throw new DataTableConfigurationException('You must specify a title callback for a WireLink column.');
+ }
+
+ if (! $this->hasActionCallback()) {
+ throw new DataTableConfigurationException('You must specify an action callback for a WireLink column.');
+ }
+
+ return view($this->getView())
+ ->withColumn($this)
+ ->withTitle(app()->call($this->getTitleCallback(), ['row' => $row]))
+ ->withPath(app()->call($this->getActionCallback(), ['row' => $row]))
+ ->withAttributes($this->hasAttributesCallback() ? app()->call($this->getAttributesCallback(), ['row' => $row]) : []);
+ }
+}
diff --git a/src/Views/Traits/Configuration/WireLinkColumnConfiguration.php b/src/Views/Traits/Configuration/WireLinkColumnConfiguration.php
new file mode 100644
index 000000000..b2aa49683
--- /dev/null
+++ b/src/Views/Traits/Configuration/WireLinkColumnConfiguration.php
@@ -0,0 +1,7 @@
+actionCallback = $callback;
+
+ return $this;
+ }
+
+ public function getActionCallback(): ?callable
+ {
+ return $this->actionCallback;
+ }
+
+ public function hasActionCallback(): bool
+ {
+ return $this->actionCallback !== null;
+ }
+}
diff --git a/src/Views/Traits/Core/HasConfirmation.php b/src/Views/Traits/Core/HasConfirmation.php
new file mode 100644
index 000000000..9a8597947
--- /dev/null
+++ b/src/Views/Traits/Core/HasConfirmation.php
@@ -0,0 +1,28 @@
+confirmMessage = $confirmMessage;
+
+ return $this;
+ }
+
+ public function hasConfirmMessage(): bool
+ {
+ return isset($this->confirmMessage);
+ }
+
+ public function getConfirmMessage(): string
+ {
+ return $this->confirmMessage;
+ }
+}
diff --git a/src/Views/Traits/Helpers/WireLinkColumnHelpers.php b/src/Views/Traits/Helpers/WireLinkColumnHelpers.php
new file mode 100644
index 000000000..d342db23a
--- /dev/null
+++ b/src/Views/Traits/Helpers/WireLinkColumnHelpers.php
@@ -0,0 +1,7 @@
+assertSame('Name', $column->getTitle());
+ }
+
+ /** @test */
+ public function can_not_infer_field_name_from_title_if_no_from(): void
+ {
+ $column = WireLinkColumn::make('My Title');
+
+ $this->assertNull($column->getField());
+ }
+
+ /** @test */
+ public function can_not_render_field_if_no_title_callback(): void
+ {
+ $this->expectException(DataTableConfigurationException::class);
+
+ WireLinkColumn::make('Name')->getContents(Pet::find(1));
+ }
+
+ /** @test */
+ public function can_not_render_field_if_no_action_callback(): void
+ {
+ $this->expectException(DataTableConfigurationException::class);
+
+ WireLinkColumn::make('Name')->title(fn ($row) => 'Edit')->getContents(Pet::find(1));
+ }
+
+ /** @test */
+ public function can_render_field_if_title_and_action_callback(): void
+ {
+ $column = WireLinkColumn::make('Name')->title(fn ($row) => 'Edit')->action(fn ($row) => 'delete("'.$row->id.'")')->getContents(Pet::find(1));
+
+ $this->assertNotEmpty($column);
+ }
+
+ /** @test */
+ public function can_render_field_if_confirm_set(): void
+ {
+ $column = WireLinkColumn::make('Name')->title(fn ($row) => 'Edit')->action(fn ($row) => 'delete("'.$row->id.'")')->confirmMessage('Test')->getContents(Pet::find(1));
+
+ $this->assertNotEmpty($column);
+ }
+}