Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add icon column #1902

Merged
merged 12 commits into from
Aug 27, 2024
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
Loading