Skip to content

Commit f202650

Browse files
committed
Merge branch 'CristhoferMF-component-column' into develop
2 parents 5211e77 + a485d2f commit f202650

File tree

6 files changed

+222
-0
lines changed

6 files changed

+222
-0
lines changed

docs/columns/other-column-types.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,28 @@ ButtonGroupColumn::make('Actions')
159159
}),
160160
]),
161161
```
162+
163+
## Component Columns
164+
165+
Component columns let you specify a component name and attributes and provides the column value to the slot.
166+
167+
```php
168+
// Before
169+
Column::make("Email", "email")
170+
->format(function ($value) {
171+
return view('components.alert')
172+
->with('attributes', new ComponentAttributeBag([
173+
'type' => Str::endsWith($value, 'example.org') ? 'success' : 'danger',
174+
'dismissible' => true,
175+
]))
176+
->with('slot', $value);
177+
}),
178+
179+
// After
180+
ComponentColumn::make('E-mail', 'email')
181+
->component('email')
182+
->attributes(fn ($value, $row, Column $column) => [
183+
'type' => Str::endsWith($value, 'example.org') ? 'success' : 'danger',
184+
'dismissible' => true,
185+
]),
186+
```

src/Views/Columns/ComponentColumn.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views\Columns;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Support\HtmlString;
7+
use Illuminate\View\ComponentAttributeBag;
8+
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
9+
use Rappasoft\LaravelLivewireTables\Views\Column;
10+
use Rappasoft\LaravelLivewireTables\Views\Traits\Configuration\ComponentColumnConfiguration;
11+
use Rappasoft\LaravelLivewireTables\Views\Traits\Helpers\ComponentColumnHelpers;
12+
13+
class ComponentColumn extends Column
14+
{
15+
use ComponentColumnHelpers,
16+
ComponentColumnConfiguration;
17+
18+
protected string $componentView;
19+
protected $attributesCallback;
20+
protected $slotCallback;
21+
22+
public function __construct(string $title, string $from = null)
23+
{
24+
parent::__construct($title, $from);
25+
}
26+
27+
public function getContents(Model $row)
28+
{
29+
if ($this->isLabel()) {
30+
throw new DataTableConfigurationException('You can not use a label column with a component column');
31+
}
32+
33+
if (false === $this->hasComponentView()) {
34+
throw new DataTableConfigurationException('You must specify a component view for a component column');
35+
}
36+
37+
$attributes = [];
38+
$value = $this->getValue($row);
39+
$slotContent = $value;
40+
41+
if ($this->hasAttributesCallback()) {
42+
$attributes = call_user_func($this->getAttributesCallback(), $value, $row, $this);
43+
44+
if (!is_array($attributes)) {
45+
throw new DataTableConfigurationException('The return type of callback must be an array');
46+
}
47+
}
48+
if ($this->hasSlotCallback()) {
49+
$slotContent = call_user_func($this->getSlotCallback(), $value, $row, $this);
50+
if (is_string($slotContent)) {
51+
$slotContent = new HtmlString($slotContent);
52+
}
53+
}
54+
55+
return view($this->getComponentView(), [
56+
'attributes' => new ComponentAttributeBag($attributes),
57+
'slot' => $slotContent,
58+
]);
59+
}
60+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views\Traits\Configuration;
4+
5+
trait ComponentColumnConfiguration
6+
{
7+
public function component(string $component): self
8+
{
9+
$this->componentView = 'components.' . $component;
10+
return $this;
11+
}
12+
13+
public function attributes(callable $callback): self
14+
{
15+
$this->attributesCallback = $callback;
16+
return $this;
17+
}
18+
19+
public function slot(callable $callback): self
20+
{
21+
$this->slotCallback = $callback;
22+
return $this;
23+
}
24+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views\Traits\Helpers;
4+
5+
trait ComponentColumnHelpers
6+
{
7+
public function getAttributesCallback()
8+
{
9+
return $this->attributesCallback;
10+
}
11+
12+
public function hasAttributesCallback(): bool
13+
{
14+
return $this->attributesCallback !== null;
15+
}
16+
17+
public function getSlotCallback()
18+
{
19+
return $this->slotCallback;
20+
}
21+
22+
public function hasSlotCallback(): bool
23+
{
24+
return $this->slotCallback !== null;
25+
}
26+
27+
/**
28+
* Get the value of componentView
29+
*/
30+
public function getComponentView()
31+
{
32+
return $this->componentView;
33+
}
34+
35+
public function hasComponentView(): bool
36+
{
37+
return isset($this->componentView);
38+
}
39+
}

tests/Views/ComponentColumnTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Tests\Views;
4+
5+
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
6+
use Rappasoft\LaravelLivewireTables\Tests\Models\Pet;
7+
use Rappasoft\LaravelLivewireTables\Tests\TestCase;
8+
use Rappasoft\LaravelLivewireTables\Views\Columns\ComponentColumn;
9+
10+
class ComponentColumnTest extends TestCase
11+
{
12+
/** @test */
13+
public function component_column_attributes_callback_return_can_not_be_an_string()
14+
{
15+
$this->expectException(DataTableConfigurationException::class);
16+
ComponentColumn::make('Name')
17+
->component('alert')
18+
->attributes(fn () => 'string')->getContents(Pet::find(1));
19+
}
20+
21+
/** @test */
22+
public function component_column_component_has_to_be_an_string()
23+
{
24+
$column = ComponentColumn::make('Name')
25+
->component('alert');
26+
$this->assertEquals('components.alert', $column->getComponentView());
27+
}
28+
29+
/** @test */
30+
public function component_column_component_view_has_to_be_set()
31+
{
32+
$this->expectException(DataTableConfigurationException::class);
33+
ComponentColumn::make('Name')
34+
->getContents(Pet::find(1));
35+
}
36+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Tests\Views\Traits\Configuration;
4+
5+
use Closure;
6+
use Rappasoft\LaravelLivewireTables\Tests\TestCase;
7+
use Rappasoft\LaravelLivewireTables\Views\Columns\ComponentColumn;
8+
9+
class ComponentColumnConfigurationTest extends TestCase
10+
{
11+
/** @test */
12+
public function component_column_can_set_slot_callback(): void
13+
{
14+
$column = ComponentColumn::make('Name');
15+
16+
$this->assertFalse($column->hasSlotCallback());
17+
18+
$column->slot(fn ($value) => $value);
19+
20+
$this->assertTrue($column->hasSlotCallback());
21+
22+
$this->assertTrue($column->getSlotCallback() instanceof Closure);
23+
}
24+
25+
/** @test */
26+
public function component_column_can_set_attributes_callback(): void
27+
{
28+
$column = ComponentColumn::make('Name');
29+
30+
$this->assertFalse($column->hasAttributesCallback());
31+
32+
$column->attributes(fn ($value) => $value);
33+
34+
$this->assertTrue($column->hasAttributesCallback());
35+
36+
$this->assertTrue($column->getAttributesCallback() instanceof Closure);
37+
}
38+
}

0 commit comments

Comments
 (0)