diff --git a/docs/column-types/view_component_column.md b/docs/column-types/view_component_column.md new file mode 100644 index 000000000..1df2ea7a3 --- /dev/null +++ b/docs/column-types/view_component_column.md @@ -0,0 +1,32 @@ +--- +title: View Component Columns +weight: 14 +--- + +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. + +```php + +ViewComponentColumn::make('E-mail', 'email') + ->component('email') + ->attributes(fn ($value, $row, Column $column) => [ + 'id' => $row->id, + 'email' => $value, + ]), +``` + +Please also see the following for other available methods: + \ No newline at end of file diff --git a/docs/column-types/wire_link_column.md b/docs/column-types/wire_link_column.md index eaee09537..9abf15aac 100644 --- a/docs/column-types/wire_link_column.md +++ b/docs/column-types/wire_link_column.md @@ -1,6 +1,6 @@ --- title: Wire Link Column (beta) -weight: 14 +weight: 15 --- 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 diff --git a/src/Views/Columns/ViewComponentColumn.php b/src/Views/Columns/ViewComponentColumn.php new file mode 100644 index 000000000..91b3ec5ff --- /dev/null +++ b/src/Views/Columns/ViewComponentColumn.php @@ -0,0 +1,51 @@ +html(); + + } + + public function getContents(Model $row): null|string|HtmlString|DataTableConfigurationException|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View + { + if ($this->isLabel()) { + throw new DataTableConfigurationException('You can not use a label column with a component column'); + } + + if ($this->hasComponentView() === false) { + throw new DataTableConfigurationException('You must specify a component view for a component column'); + } + + $value = $this->getValue($row); + $attributes = ['value' => $value]; + + if ($this->hasAttributesCallback()) { + $attributes = call_user_func($this->getAttributesCallback(), $value, $row, $this); + + if (! is_array($attributes)) { + throw new DataTableConfigurationException('The return type of callback must be an array'); + } + } + + return \Illuminate\Support\Facades\Blade::render( + 'getComponentView().' '.new ComponentAttributeBag($attributes).' />'); + } +} diff --git a/src/Views/Traits/Configuration/ViewComponentColumnConfiguration.php b/src/Views/Traits/Configuration/ViewComponentColumnConfiguration.php new file mode 100644 index 000000000..7e0300854 --- /dev/null +++ b/src/Views/Traits/Configuration/ViewComponentColumnConfiguration.php @@ -0,0 +1,16 @@ +componentView = $component; + + return $this; + } +} diff --git a/src/Views/Traits/Helpers/ViewComponentColumnHelpers.php b/src/Views/Traits/Helpers/ViewComponentColumnHelpers.php new file mode 100644 index 000000000..8de648e84 --- /dev/null +++ b/src/Views/Traits/Helpers/ViewComponentColumnHelpers.php @@ -0,0 +1,22 @@ +componentView; + } + + /** + * Determines whether a Component View has been set + */ + public function hasComponentView(): bool + { + return isset($this->componentView); + } +} diff --git a/tests/Http/TestComponent.php b/tests/Http/TestComponent.php new file mode 100644 index 000000000..7fa31a7ba --- /dev/null +++ b/tests/Http/TestComponent.php @@ -0,0 +1,27 @@ +testItem = $age * 110; + } + + /** + * Get the view / contents that represent the component. + */ + public function render(): View|Closure|string + { + return \Illuminate\Support\Facades\Blade::render( + '
'.($this->testItem ?? 'Unknown').'
'); + + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index ab22227bd..2a9a2479a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,11 +5,13 @@ use BladeUI\Heroicons\BladeHeroiconsServiceProvider; use BladeUI\Icons\BladeIconsServiceProvider; use Illuminate\Encryption\Encrypter; +use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\DB; use Livewire\LivewireServiceProvider; use Orchestra\Testbench\TestCase as Orchestra; use Rappasoft\LaravelLivewireTables\LaravelLivewireTablesServiceProvider; use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\{PetsTable,PetsTableUnpaginated,SpeciesTable}; +use Rappasoft\LaravelLivewireTables\Tests\Http\TestComponent; use Rappasoft\LaravelLivewireTables\Tests\Models\Breed; use Rappasoft\LaravelLivewireTables\Tests\Models\Pet; use Rappasoft\LaravelLivewireTables\Tests\Models\Species; @@ -30,6 +32,8 @@ protected function setUp(): void { parent::setUp(); + Blade::component('test-component', TestComponent::class); + if (! Breed::where('id', 1)->get()) { include_once __DIR__.'/../database/migrations/create_test_tables.php.stub'; (new \CreateTestTables())->down(); diff --git a/tests/Views/Columns/ViewComponentColumnTest.php b/tests/Views/Columns/ViewComponentColumnTest.php new file mode 100644 index 000000000..ae40b89d5 --- /dev/null +++ b/tests/Views/Columns/ViewComponentColumnTest.php @@ -0,0 +1,55 @@ +assertSame('Total Users', $column->getTitle()); + } + + public function test_can_have_component_view(): void + { + $column = ViewComponentColumn::make('Age 2', 'age') + ->component('test-component') + ->attributes(fn ($value, $row, Column $column) => [ + 'age' => $row->age, + ]); + $this->assertTrue($column->hasComponentView()); + } + + public function test_can_not_omit_component(): void + { + $this->expectException(DataTableConfigurationException::class); + + $column = ViewComponentColumn::make('Age 2', 'age') + ->attributes(fn ($value, $row, Column $column) => [ + 'age' => $row->age, + ]); + $contents = $column->getContents(Pet::find(1)); + $this->assertSame('
2420
', $contents); + + } + + public function test_can_render_component(): void + { + + $column = ViewComponentColumn::make('Age 2', 'age') + ->component('test-component') + ->attributes(fn ($value, $row, Column $column) => [ + 'age' => $row->age, + ]); + $contents = $column->getContents(Pet::find(1)); + $this->assertSame('
2420
', $contents); + + } +}