Skip to content

Commit

Permalink
Add icon column (#1902)
Browse files Browse the repository at this point in the history
* Initial Commit - Awaiting Docs & Tests

* Tweak to IconColumn label behaviour

* Adding IconColumn documentation

* Add Additional Tests - Replace Test Database

* Add Visuals Test for IconColumn

* Add Icon Columns to Other Column Types

* Undo FrontendAssetsTest Changes

---------

Co-authored-by: lrljoe <[email protected]>
  • Loading branch information
lrljoe and lrljoe authored Aug 27, 2024
1 parent 0b0d9cb commit 0882827
Show file tree
Hide file tree
Showing 17 changed files with 361 additions and 9 deletions.
Binary file not shown.
87 changes: 87 additions & 0 deletions docs/column-types/icon_column.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: Icon Columns (beta)
weight: 10
---

Icon columns provide a way to display icons in your table without having to use `format()` or partial views.

### setIcon
setIcon requires a valid path to an SVG (Directly or via a Library), it receives the $row, and $value (if available) to help you customise which icon to use
```php
IconColumn::make('Icon', 'status')
->setIcon(function ($row, $value) {
if($value == 1) {
return "heroicon-o-check-circle";
}
else
{
return "heroicon-o-x-circle";
}
}),
```

### attributes
Attributes receives the $row, and $value (if available) to help you customise which attributes to apply, you may pass both classes, and other SVG specific attributes.
```php
IconColumn::make('Icon', 'status')
->setIcon(function ($row, $value) { if($value == 1) { return "heroicon-o-check-circle"; } else { return "heroicon-o-x-circle"; } })
->attributes(function ($row, $value) {
if($value == 1) {
return [
'class' => 'w-6 h-6',
'stroke' => '#008000'
];
}
else
{
return [
'class' => 'w-3 h-3',
'stroke' => '#FF0000'
];
}
}),
```

For example:
### Example
```php
IconColumn::make('Icon', 'status')
->setIcon(function ($row, $value) { if($value == 1) { return "heroicon-o-check-circle"; } else { return "heroicon-o-x-circle"; } })
->attributes(function ($row, $value) {
if($value == 3) {
return [
'class' => 'w-3 h-3',
'stroke' => '#008000'
];
}
else if($value == 2) {
return [
'class' => 'w-3 h-3',
'stroke' => '#0000FF'
];
}
else
{
return [
'class' => 'w-3 h-3',
'stroke' => '#FF0000'
];
}
}),
```

Please also see the following for other available methods:
<ul>
<li>
<a href="https://rappasoft.com/docs/laravel-livewire-tables/v3/columns/available-methods">Available Methods</a>
</li>
<li>
<a href="https://rappasoft.com/docs/laravel-livewire-tables/v3/columns/column-selection">Column Selection</a>
</li>
<li>
<a href="https://rappasoft.com/docs/laravel-livewire-tables/v3/columns/secondary-header">Secondary Header</a>
</li>
<li>
<a href="https://rappasoft.com/docs/laravel-livewire-tables/v3/columns/footer">Footer</a>
</li>
</ul>
2 changes: 1 addition & 1 deletion docs/column-types/image_columns.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Image Columns
weight: 10
weight: 11
---

Image columns provide a way to display images in your table without having to use `format()` or partial views:
Expand Down
2 changes: 1 addition & 1 deletion docs/column-types/link_columns.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Link Columns
weight: 11
weight: 12
---

Link columns provide a way to display HTML links in your table without having to use `format()` or partial views:
Expand Down
2 changes: 1 addition & 1 deletion docs/column-types/livewire_component_column.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Livewire Component (beta)
weight: 12
weight: 13
---

Livewire Component Columns allow for the use of a Livewire Component as a Column.
Expand Down
2 changes: 1 addition & 1 deletion docs/column-types/sum_column.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Sum Columns (beta)
weight: 13
weight: 14
---

Sum columns provide an easy way to display the "Sum" of a field on a relation.
Expand Down
2 changes: 1 addition & 1 deletion docs/column-types/view_component_column.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: View Component Columns
weight: 14
weight: 15
---

View Component columns let you specify a component name and attributes and provide attributes to the View Component. This will render the View Component in it's entirety.
Expand Down
2 changes: 1 addition & 1 deletion docs/column-types/wire_link_column.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Wire Link Column (beta)
weight: 15
weight: 16
---

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
Expand Down
3 changes: 3 additions & 0 deletions docs/columns/other-column-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ weight: 4
<li>
<a href="https://rappasoft.com/docs/laravel-livewire-tables/v3/column-types/date_columns">Date Columns</a>
</li>
<li>
[Icon Columns (Beta)](../column-types/icon_columns)
</li>
<li>
<a href="https://rappasoft.com/docs/laravel-livewire-tables/v3/column-types/image_columns">Image Columns</a>
</li>
Expand Down
7 changes: 7 additions & 0 deletions resources/views/includes/columns/icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div class="livewire-tables-columns-icon">
@svg(
$icon,
$classes,
$attributes,
)
</div>
43 changes: 43 additions & 0 deletions src/Views/Columns/IconColumn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Columns;

use Illuminate\Database\Eloquent\Model;
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
use Rappasoft\LaravelLivewireTables\Views\Column;
use Rappasoft\LaravelLivewireTables\Views\Traits\Configuration\IconColumnConfiguration;
use Rappasoft\LaravelLivewireTables\Views\Traits\Helpers\IconColumnHelpers;
use Rappasoft\LaravelLivewireTables\Views\Traits\IsColumn;

class IconColumn extends Column
{
use IsColumn;
use IconColumnConfiguration,
IconColumnHelpers;

public ?\Closure $iconCallback;

protected string $view = 'livewire-tables::includes.columns.icon';

public function __construct(string $title, ?string $from = null)
{
parent::__construct($title, $from);
if (! isset($from)) {
$this->label(fn () => null);
}

$this->html();
}

public function getContents(Model $row): null|string|\Illuminate\Support\HtmlString|DataTableConfigurationException|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
{
$attributeBag = $this->getAttributeBag($row);

return view($this->getView())
->withIsTailwind($this->isTailwind())
->withIsBootstrap($this->isBootstrap())
->withIcon($this->getIcon($row))
->withClasses($attributeBag['class'])
->withAttributes(collect($attributeBag)->except('class')->toArray());
}
}
13 changes: 13 additions & 0 deletions src/Views/Traits/Configuration/IconColumnConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Configuration;

trait IconColumnConfiguration
{
public function setIcon(\Closure $callback): self
{
$this->iconCallback = $callback;

return $this;
}
}
2 changes: 1 addition & 1 deletion src/Views/Traits/Core/HasAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function hasAttributesCallback(): bool
// TODO: Test
public function getAttributeBag(Model $row): ComponentAttributeBag
{
return new ComponentAttributeBag($this->hasAttributesCallback() ? app()->call($this->getAttributesCallback(), ['row' => $row]) : []);
return new ComponentAttributeBag($this->hasAttributesCallback() ? app()->call($this->getAttributesCallback(), ['row' => $row, 'value' => $this->getValue($row)]) : []);
}

/**
Expand Down
27 changes: 27 additions & 0 deletions src/Views/Traits/Helpers/IconColumnHelpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Helpers;

use Illuminate\Database\Eloquent\Model;
use Illuminate\View\ComponentAttributeBag;
use Rappasoft\LaravelLivewireTables\Views\Traits\Columns\HasDefaultStringValue;

trait IconColumnHelpers
{
use HasDefaultStringValue;

public function getIcon(Model $row): string
{
return $this->hasIconCallback() ? app()->call($this->getIconCallback(), ['row' => $row, 'value' => $this->getValue($row) ?? '']) : ($this->getValue($row));
}

public function getIconCallback(): ?callable
{
return $this->iconCallback;
}

public function hasIconCallback(): bool
{
return isset($this->iconCallback);
}
}
4 changes: 2 additions & 2 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,10 @@ public function getEnvironmentSetUp($app): void
$app['config']->set('view.cache', false);
$app['config']->set('view.compiled', realpath(storage_path('framework/views')).'/'.rand(0, 100));

if (file_exists(__DIR__.'/../database/sqlite.database')) {
if (file_exists(__DIR__.'/../database/database.sqlite')) {
$app['config']->set('database.connections.sqlite', [
'driver' => 'sqlite',
'database' => __DIR__.'/../database/sqlite.database',
'database' => __DIR__.'/../database/database.sqlite',
'prefix' => '',
]);
} else {
Expand Down
64 changes: 64 additions & 0 deletions tests/Traits/Visuals/Columns/IconColumnVisualsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Tests\Traits\Visuals\Columns;

use Exception;
use Illuminate\View\ViewException;
use Livewire\Livewire;
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\FailingTables\{BrokenSecondaryHeaderTable, NoBuildMethodTable, NoPrimaryKeyTable};
use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\{PetsTable,PetsTableAttributes};
use Rappasoft\LaravelLivewireTables\Tests\TestCase;

final class IconColumnVisualsTest extends TestCase
{
private $testErrors;

public function test_icon_column_renders_correctly(): void
{
Livewire::test(new class extends PetsTable
{
public function configure(): void
{
$this->setPrimaryKey('id');
}

public function columns(): array
{
return [
\Rappasoft\LaravelLivewireTables\Views\Column::make('Name')->searchable(),
\Rappasoft\LaravelLivewireTables\Views\Columns\IconColumn::make('Old Age', 'age')
->setIcon(function (\Rappasoft\LaravelLivewireTables\Tests\Models\Pet $row, int $value) {
if ($value >= 5) {
return 'heroicon-o-check-circle';
} else {
return 'heroicon-o-x-circle';
}
}),
];
}

public function filters(): array
{
return [];
}
})
->call('setSearch', 'Cartman')
->assertSeeHtmlInOrder([
'<div class="livewire-tables-columns-icon">',
'<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">',
'<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>',
'</svg></div>',
])
->assertDontSeeHtml('<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>')
->call('setSearch', 'May')
->assertDontSeeHtml('<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>')
->assertSeeHtmlInOrder([
'<div class="livewire-tables-columns-icon">',
'<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon">',
'<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>',
'</svg></div>',
]);

}
}
Loading

0 comments on commit 0882827

Please sign in to comment.