diff --git a/CHANGELOG.md b/CHANGELOG.md
index ea686d326..93bd62c02 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,25 @@
All notable changes to `laravel-livewire-tables` will be documented in this file
+## [v3.5.7] - 2024-12-01
+### New Features
+- IncrementColumn by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2096
+- Add setFilterPopoverAttributes by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2101
+
+### Tweaks
+- Remove View TypeHinting in blades due to reported errors by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2097
+
+### Blades
+- Remove $component from blades to improve performance by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2098
+
+### Testing
+- Exclude config/database from sources by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2102
+- Add missing tests for WithCustomisations by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2104
+- Ignore WithEvents Coverage by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2105
+- Add Search Lazy Tests by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2106
+- Add extra Search Lazy Tests by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2107
+
+
## [v3.5.6] - 2024-11-28
### New Features
- Add Icon to Search Input by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2092
diff --git a/docs/column-types/increment_column.md b/docs/column-types/increment_column.md
new file mode 100644
index 000000000..76ea7496c
--- /dev/null
+++ b/docs/column-types/increment_column.md
@@ -0,0 +1,12 @@
+---
+title: Increment Column (beta)
+weight: 12
+---
+
+The IncrementColumn provides an easy way to display the row's index in the loop.
+
+Please note - this is not linked to the row's primary key!
+
+```php
+ IncrementColumn::make('#'),
+```
\ No newline at end of file
diff --git a/docs/column-types/link_columns.md b/docs/column-types/link_columns.md
index 1e4aa7fa1..7c36ee077 100644
--- a/docs/column-types/link_columns.md
+++ b/docs/column-types/link_columns.md
@@ -1,6 +1,6 @@
---
title: Link Columns
-weight: 12
+weight: 13
---
Link columns provide a way to display HTML links in your table without having to use `format()` or partial views:
diff --git a/docs/column-types/livewire_component_column.md b/docs/column-types/livewire_component_column.md
index 6a6af2eea..ebeb72724 100644
--- a/docs/column-types/livewire_component_column.md
+++ b/docs/column-types/livewire_component_column.md
@@ -1,6 +1,6 @@
---
title: Livewire Component (beta)
-weight: 13
+weight: 14
---
Livewire Component Columns allow for the use of a Livewire Component as a Column.
diff --git a/docs/column-types/sum_column.md b/docs/column-types/sum_column.md
index b15288ef2..638818b23 100644
--- a/docs/column-types/sum_column.md
+++ b/docs/column-types/sum_column.md
@@ -1,6 +1,6 @@
---
title: Sum Columns (beta)
-weight: 14
+weight: 15
---
Sum columns provide an easy way to display the "Sum" of a field on a relation.
diff --git a/docs/column-types/view_component_column.md b/docs/column-types/view_component_column.md
index f3dd04276..5fdb4b46d 100644
--- a/docs/column-types/view_component_column.md
+++ b/docs/column-types/view_component_column.md
@@ -1,6 +1,6 @@
---
title: View Component Columns
-weight: 15
+weight: 16
---
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.
diff --git a/docs/column-types/wire_link_column.md b/docs/column-types/wire_link_column.md
index 253544cd0..63c23e8a2 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: 16
+weight: 17
---
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/docs/filters/available-methods.md b/docs/filters/available-methods.md
index 5246704e9..820916003 100644
--- a/docs/filters/available-methods.md
+++ b/docs/filters/available-methods.md
@@ -206,6 +206,30 @@ public function configure(): void
}
```
+### setFilterPopoverAttributes
+
+Allows for the customisation of the appearance of the Filter Popover Menu.
+
+Note the addition of a "default-width" boolean, allowing you to customise the width more smoothly without impacting other applied classes.
+
+You may also replace default colors by setting "default-colors" to false, or default styling by setting "default-styling" to false, and specifying replacement classes in the "class" property.
+
+You can also replace the default transition behaviours (Tailwind) by specifying replacement attributes in the array.
+
+```php
+public function configure(): void
+{
+ $this->setFilterPopoverAttributes(
+ [
+ 'class' => 'w-96',
+ 'default-width' => false,
+ 'default-colors' => true,
+ 'default-styling' => true,
+ 'x-transition:enter' => 'transition ease-out duration-100',
+ ]
+ );
+}
+```
----
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 5dea165fe..1d717c349 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -21,8 +21,6 @@
- config
- database
src
diff --git a/resources/views/components/pagination.blade.php b/resources/views/components/pagination.blade.php
index dedf4507d..4a9ffca95 100644
--- a/resources/views/components/pagination.blade.php
+++ b/resources/views/components/pagination.blade.php
@@ -1,4 +1,4 @@
-@aware(['component','isTailwind','isBootstrap','isBootstrap4','isBootstrap5'])
+@aware(['isTailwind','isBootstrap','isBootstrap4','isBootstrap5'])
@includeWhen(
$this->hasConfigurableAreaFor('before-pagination'),
diff --git a/resources/views/components/table.blade.php b/resources/views/components/table.blade.php
index 331c0b25f..87d0c3c05 100644
--- a/resources/views/components/table.blade.php
+++ b/resources/views/components/table.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName','isTailwind','isBootstrap'])
+@aware([ 'tableName','isTailwind','isBootstrap'])
@php
$customAttributes = [
diff --git a/resources/views/components/table/collapsed-columns.blade.php b/resources/views/components/table/collapsed-columns.blade.php
index b15e9cf20..f773bd8ae 100644
--- a/resources/views/components/table/collapsed-columns.blade.php
+++ b/resources/views/components/table/collapsed-columns.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName', 'primaryKey','isTailwind','isBootstrap'])
+@aware([ 'tableName', 'primaryKey','isTailwind','isBootstrap'])
@props(['row', 'rowIndex'])
@php
@@ -50,7 +50,6 @@
colspan="{{ $colspan }}"
>
- @php /** @var \Rappasoft\LaravelLivewireTables\Views\Column $column */ @endphp
@foreach($columns as $colIndex => $column)
@continue($column->isHidden())
@continue($this->columnSelectIsEnabled() && ! $this->columnSelectIsEnabledForColumn($column))
diff --git a/resources/views/components/table/empty.blade.php b/resources/views/components/table/empty.blade.php
index a5f1b5d22..705f93d48 100644
--- a/resources/views/components/table/empty.blade.php
+++ b/resources/views/components/table/empty.blade.php
@@ -1,4 +1,4 @@
-@aware(['component','isTailwind','isBootstrap'])
+@aware(['isTailwind','isBootstrap'])
@php($attributes = $attributes->merge(['wire:key' => 'empty-message-'.$this->getId()]))
diff --git a/resources/views/components/table/td.blade.php b/resources/views/components/table/td.blade.php
index 8320d2d9f..546bf33fe 100644
--- a/resources/views/components/table/td.blade.php
+++ b/resources/views/components/table/td.blade.php
@@ -1,8 +1,7 @@
-@aware(['component', 'row', 'rowIndex', 'tableName', 'primaryKey','isTailwind','isBootstrap'])
+@aware([ 'row', 'rowIndex', 'tableName', 'primaryKey','isTailwind','isBootstrap'])
@props(['column', 'colIndex'])
@php
- /** @var \Rappasoft\LaravelLivewireTables\Views\Column $column */
$customAttributes = $this->getTdAttributes($column, $row, $colIndex, $rowIndex)
@endphp
diff --git a/resources/views/components/table/td/bulk-actions.blade.php b/resources/views/components/table/td/bulk-actions.blade.php
index 918743395..df5338f7f 100644
--- a/resources/views/components/table/td/bulk-actions.blade.php
+++ b/resources/views/components/table/td/bulk-actions.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName','primaryKey'])
+@aware([ 'tableName','primaryKey'])
@props(['row', 'rowIndex'])
@php
diff --git a/resources/views/components/table/td/collapsed-columns.blade.php b/resources/views/components/table/td/collapsed-columns.blade.php
index 166a62138..3bf65e170 100644
--- a/resources/views/components/table/td/collapsed-columns.blade.php
+++ b/resources/views/components/table/td/collapsed-columns.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName','isTailwind','isBootstrap'])
+@aware([ 'tableName','isTailwind','isBootstrap'])
@props(['rowIndex', 'hidden' => false])
@if ($this->collapsingColumnsAreEnabled() && $this->hasCollapsedColumns())
diff --git a/resources/views/components/table/td/plain.blade.php b/resources/views/components/table/td/plain.blade.php
index 824bcf2af..417f6c6b6 100644
--- a/resources/views/components/table/td/plain.blade.php
+++ b/resources/views/components/table/td/plain.blade.php
@@ -1,7 +1,6 @@
-@aware(['component', 'rowIndex', 'rowID','isTailwind','isBootstrap'])
+@aware([ 'rowIndex', 'rowID','isTailwind','isBootstrap'])
@props(['column' => null, 'customAttributes' => [], 'displayMinimisedOnReorder' => false, 'hideUntilReorder' => false])
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Column|null $column */ @endphp
@if ($isTailwind)
getTheme())
diff --git a/resources/views/components/table/th.blade.php b/resources/views/components/table/th.blade.php
index ee837bf28..525833fe7 100644
--- a/resources/views/components/table/th.blade.php
+++ b/resources/views/components/table/th.blade.php
@@ -1,8 +1,7 @@
-@aware(['component', 'tableName','isTailwind','isBootstrap'])
+@aware([ 'tableName','isTailwind','isBootstrap'])
@props(['column', 'index'])
@php
- /** @var \Rappasoft\LaravelLivewireTables\Views\Column $column */
$attributes = $attributes->merge(['wire:key' => $tableName . '-header-col-'.$column->getSlug()]);
$allThAttributes = $this->getAllThAttributes($column);
diff --git a/resources/views/components/table/th/bulk-actions.blade.php b/resources/views/components/table/th/bulk-actions.blade.php
index c5c6d3e6c..d15f5a728 100644
--- a/resources/views/components/table/th/bulk-actions.blade.php
+++ b/resources/views/components/table/th/bulk-actions.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName'])
+@aware([ 'tableName'])
@php
$customAttributes = $this->hasBulkActionsThAttributes ? $this->getBulkActionsThAttributes : $this->getAllThAttributes($this->getBulkActionsColumn())['customAttributes'];
diff --git a/resources/views/components/table/th/collapsed-columns.blade.php b/resources/views/components/table/th/collapsed-columns.blade.php
index 4965c2dd2..eebc53e70 100644
--- a/resources/views/components/table/th/collapsed-columns.blade.php
+++ b/resources/views/components/table/th/collapsed-columns.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName','isTailwind','isBootstrap'])
+@aware([ 'tableName','isTailwind','isBootstrap'])
@if ($this->collapsingColumnsAreEnabled() && $this->hasCollapsedColumns())
@if ($isTailwind)
diff --git a/resources/views/components/table/th/plain.blade.php b/resources/views/components/table/th/plain.blade.php
index 3a0a56d36..0b9c8326e 100644
--- a/resources/views/components/table/th/plain.blade.php
+++ b/resources/views/components/table/th/plain.blade.php
@@ -1,4 +1,4 @@
-@aware(['component','isTailwind','isBootstrap'])
+@aware(['isTailwind','isBootstrap'])
@props(['displayMinimisedOnReorder' => false, 'hideUntilReorder' => false, 'customAttributes' => ['default' => true]])
bulkActionsAreEnabled() && $this->hasBulkActions())
@php
diff --git a/resources/views/components/table/tr/footer.blade.php b/resources/views/components/table/tr/footer.blade.php
index ba0ecc51e..d9681d779 100644
--- a/resources/views/components/table/tr/footer.blade.php
+++ b/resources/views/components/table/tr/footer.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName'])
+@aware([ 'tableName'])
[], 'displayMinimisedOnReorder' => true])
@if ($isTailwind)
diff --git a/resources/views/components/table/tr/secondary-header.blade.php b/resources/views/components/table/tr/secondary-header.blade.php
index a6a7cc5f3..6e3ca28c0 100644
--- a/resources/views/components/table/tr/secondary-header.blade.php
+++ b/resources/views/components/table/tr/secondary-header.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName'])
+@aware([ 'tableName'])
getToolsAttributesBag())
'popover', 'tableName' => 'table', 'isTailwind' => false, 'isBootstrap' => false, 'isBootstrap4' => false, 'isBootstrap5' => false, 'for' => null])
@php
- /** @var \Rappasoft\LaravelLivewireTables\Views\Filter $filter */
$filterLabelAttributes = $filter->getFilterLabelAttributes();
$customLabelAttributes = $filter->getLabelAttributes();
@endphp
diff --git a/resources/views/components/tools/filter-pills.blade.php b/resources/views/components/tools/filter-pills.blade.php
index 400de52b9..c0817ea97 100644
--- a/resources/views/components/tools/filter-pills.blade.php
+++ b/resources/views/components/tools/filter-pills.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5'])
+@aware([ 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5'])
@if ($this->filtersAreEnabled() && $this->filterPillsAreEnabled() && $this->hasAppliedVisibleFiltersForPills())
@@ -14,7 +14,6 @@
@foreach($this->getAppliedFiltersWithValues() as $filterSelectName => $value)
- @php /** @var \Rappasoft\LaravelLivewireTables\Views\Filter $filter */ @endphp
@php($filter = $this->getFilterByKey($filterSelectName))
@continue(is_null($filter) || $filter->isHiddenFromPills())
@php( $filterPillTitle = $filter->getFilterPillTitle())
diff --git a/resources/views/components/tools/filters/boolean.blade.php b/resources/views/components/tools/filters/boolean.blade.php
index ce7eb38c5..abc983581 100644
--- a/resources/views/components/tools/filters/boolean.blade.php
+++ b/resources/views/components/tools/filters/boolean.blade.php
@@ -1,5 +1,4 @@
@php
- /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\BooleanFilter $filter */
$defaultValue = ($filter->hasFilterDefaultValue() ? (bool) $filter->getFilterDefaultValue() : false)
@endphp
getKey();
@endphp
diff --git a/resources/views/components/tools/filters/date.blade.php b/resources/views/components/tools/filters/date.blade.php
index 3d008c9c2..e3c75f0b0 100644
--- a/resources/views/components/tools/filters/date.blade.php
+++ b/resources/views/components/tools/filters/date.blade.php
@@ -1,4 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\DateFilter $filter */ @endphp
diff --git a/resources/views/components/tools/filters/livewire-component-array-filter.blade.php b/resources/views/components/tools/filters/livewire-component-array-filter.blade.php
index e3b5f32f8..237d062fa 100644
--- a/resources/views/components/tools/filters/livewire-component-array-filter.blade.php
+++ b/resources/views/components/tools/filters/livewire-component-array-filter.blade.php
@@ -1,5 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\LivewireComponentArrayFilter $filter */ @endphp
-
diff --git a/resources/views/components/tools/filters/livewire-component-filter.blade.php b/resources/views/components/tools/filters/livewire-component-filter.blade.php
index 1b0efa654..a430faf9f 100644
--- a/resources/views/components/tools/filters/livewire-component-filter.blade.php
+++ b/resources/views/components/tools/filters/livewire-component-filter.blade.php
@@ -1,5 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\LivewireComponentFilter $filter */ @endphp
-
diff --git a/resources/views/components/tools/filters/multi-select-dropdown.blade.php b/resources/views/components/tools/filters/multi-select-dropdown.blade.php
index f1aa4afd1..a9c86ff68 100644
--- a/resources/views/components/tools/filters/multi-select-dropdown.blade.php
+++ b/resources/views/components/tools/filters/multi-select-dropdown.blade.php
@@ -1,4 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectDropdownFilter $filter */ @endphp
diff --git a/resources/views/components/tools/filters/multi-select.blade.php b/resources/views/components/tools/filters/multi-select.blade.php
index 97cc7edf7..582848bd3 100644
--- a/resources/views/components/tools/filters/multi-select.blade.php
+++ b/resources/views/components/tools/filters/multi-select.blade.php
@@ -1,4 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectFilter $filter */ @endphp
diff --git a/resources/views/components/tools/filters/number-range.blade.php b/resources/views/components/tools/filters/number-range.blade.php
index f4ebef1a4..ecdc29573 100644
--- a/resources/views/components/tools/filters/number-range.blade.php
+++ b/resources/views/components/tools/filters/number-range.blade.php
@@ -1,5 +1,4 @@
@php
- /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\NumberRangeFilter $filter */
$filterKey = $filter->getKey();
$currentMin = $minRange = $filter->getConfig('minRange');
$currentMax = $maxRange = $filter->getConfig('maxRange');
diff --git a/resources/views/components/tools/filters/number.blade.php b/resources/views/components/tools/filters/number.blade.php
index c130ef6d1..bca4f1956 100644
--- a/resources/views/components/tools/filters/number.blade.php
+++ b/resources/views/components/tools/filters/number.blade.php
@@ -1,5 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\NumberFilter $filter */ @endphp
-
diff --git a/resources/views/components/tools/filters/select.blade.php b/resources/views/components/tools/filters/select.blade.php
index 9eb3c3fdd..7ff281a76 100644
--- a/resources/views/components/tools/filters/select.blade.php
+++ b/resources/views/components/tools/filters/select.blade.php
@@ -1,5 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\SelectFilter $filter */ @endphp
-
diff --git a/resources/views/components/tools/filters/text-field.blade.php b/resources/views/components/tools/filters/text-field.blade.php
index b87f22b08..edf6898bc 100644
--- a/resources/views/components/tools/filters/text-field.blade.php
+++ b/resources/views/components/tools/filters/text-field.blade.php
@@ -1,4 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Filters\TextFilter $filter */ @endphp
diff --git a/resources/views/components/tools/sorting-pills.blade.php b/resources/views/components/tools/sorting-pills.blade.php
index 8e959e3eb..6e4266583 100644
--- a/resources/views/components/tools/sorting-pills.blade.php
+++ b/resources/views/components/tools/sorting-pills.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5'])
+@aware([ 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5'])
@if ($this->isTailwind)
@@ -7,7 +7,6 @@
{{ __($this->getLocalisationPath.'Applied Sorting') }}:
@foreach($this->getSorts() as $columnSelectName => $direction)
- @php /** @var \Rappasoft\LaravelLivewireTables\Views\Column|null $column */ @endphp
@php($column = $this->getColumnBySelectName($columnSelectName) ?? $this->getColumnBySlug($columnSelectName))
@continue(is_null($column))
@@ -49,7 +48,6 @@ class="focus:outline-none active:outline-none"
{{ __($this->getLocalisationPath.'Applied Sorting') }}:
@foreach($this->getSorts() as $columnSelectName => $direction)
- @php /** @var \Rappasoft\LaravelLivewireTables\Views\Column|null $column */ @endphp
@php($column = $this->getColumnBySelectName($columnSelectName) ?? $this->getColumnBySlug($columnSelectName))
@continue(is_null($column))
@@ -90,7 +88,6 @@ class="badge badge-pill badge-light"
{{ __($this->getLocalisationPath.'Applied Sorting') }}:
@foreach($this->getSorts() as $columnSelectName => $direction)
- @php /** @var \Rappasoft\LaravelLivewireTables\Views\Column|null $column */ @endphp
@php($column = $this->getColumnBySelectName($columnSelectName) ?? $this->getColumnBySlug($columnSelectName))
@continue(is_null($column))
diff --git a/resources/views/components/tools/toolbar.blade.php b/resources/views/components/tools/toolbar.blade.php
index bb3d57e97..36a78e787 100644
--- a/resources/views/components/tools/toolbar.blade.php
+++ b/resources/views/components/tools/toolbar.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName','isTailwind','isBootstrap'])
+@aware([ 'tableName','isTailwind','isBootstrap'])
@props([])
@php($toolBarAttributes = $this->getToolBarAttributesBag())
diff --git a/resources/views/components/tools/toolbar/items/bulk-actions.blade.php b/resources/views/components/tools/toolbar/items/bulk-actions.blade.php
index e4c9b9b25..92180299c 100644
--- a/resources/views/components/tools/toolbar/items/bulk-actions.blade.php
+++ b/resources/views/components/tools/toolbar/items/bulk-actions.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5'])
+@aware([ 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5'])
+
getSelectableSelectedColumns()->count() === $component->getSelectableColumns()->count())
- @if($component->getSelectableSelectedColumns()->count() === $component->getSelectableColumns()->count()) wire:click="deselectAllColumns" @else wire:click="selectAllColumns" @endif
+ @checked($this->getSelectableSelectedColumns()->count() === $this->getSelectableColumns()->count())
+ @if($this->getSelectableSelectedColumns()->count() === $this->getSelectableColumns()->count()) wire:click="deselectAllColumns" @else wire:click="selectAllColumns" @endif
>
{{ __($this->getLocalisationPath.'All Columns') }}
- @foreach ($component->getColumnsForColumnSelect() as $columnSlug => $columnTitle)
+ @foreach ($this->getColumnsForColumnSelect() as $columnSlug => $columnTitle)
@@ -81,10 +81,10 @@ class="text-indigo-600 rounded border-gray-300 shadow-sm transition duration-150
@elseif ($isBootstrap)
$component->getColumnSelectIsHiddenOnMobile() && $isBootstrap4,
- 'd-none d-md-block mb-3 mb-md-0 pl-0 pl-md-2' => $component->getColumnSelectIsHiddenOnTablet() && $isBootstrap4,
- 'd-none d-sm-block mb-3 mb-md-0 md-0 ms-md-2' => $component->getColumnSelectIsHiddenOnMobile() && $isBootstrap5,
- 'd-none d-md-block mb-3 mb-md-0 md-0 ms-md-2' => $component->getColumnSelectIsHiddenOnTablet() && $isBootstrap5,
+ 'd-none d-sm mb-3 mb-md-0 pl-0 pl-md-2' => $this->getColumnSelectIsHiddenOnMobile() && $isBootstrap4,
+ 'd-none d-md-block mb-3 mb-md-0 pl-0 pl-md-2' => $this->getColumnSelectIsHiddenOnTablet() && $isBootstrap4,
+ 'd-none d-sm-block mb-3 mb-md-0 md-0 ms-md-2' => $this->getColumnSelectIsHiddenOnMobile() && $isBootstrap5,
+ 'd-none d-md-block mb-3 mb-md-0 md-0 ms-md-2' => $this->getColumnSelectIsHiddenOnTablet() && $isBootstrap5,
])
>
getSelectableSelectedColumns()->count() == $component->getSelectableColumns()->count()) checked wire:click="deselectAllColumns" @else unchecked wire:click="selectAllColumns" @endif
+ @if($this->getSelectableSelectedColumns()->count() == $this->getSelectableColumns()->count()) checked wire:click="deselectAllColumns" @else unchecked wire:click="selectAllColumns" @endif
/>
{{ __($this->getLocalisationPath.'All Columns') }}
@@ -135,7 +135,7 @@ class="text-indigo-600 rounded border-gray-300 shadow-sm transition duration-150
wire:loading.attr="disabled"
type="checkbox"
class="form-check-input"
- @if($component->getSelectableSelectedColumns()->count() == $component->getSelectableColumns()->count()) checked wire:click="deselectAllColumns" @else unchecked wire:click="selectAllColumns" @endif
+ @if($this->getSelectableSelectedColumns()->count() == $this->getSelectableColumns()->count()) checked wire:click="deselectAllColumns" @else unchecked wire:click="selectAllColumns" @endif
/>
@@ -144,7 +144,7 @@ class="form-check-input"
@endif
- @foreach ($component->getColumnsForColumnSelect() as $columnSlug => $columnTitle)
+ @foreach ($this->getColumnsForColumnSelect() as $columnSlug => $columnTitle)
isBootstrap)
-
$this->isBootstrap4,
- 'dropdown-menu w-100' => $this->isBootstrap5,
- ])
- x-bind:class="{ 'show': filterPopoverOpen }"
- role="menu"
- >
- @php /** @var \Rappasoft\LaravelLivewireTables\Views\Filter $filter */ @endphp
+ merge($this->getFilterPopoverAttributes)
+ ->merge(['role' => 'menu'])
+ ->class([
+ 'w-100' => $this->getFilterPopoverAttributes['default-width'] ?? true,
+ 'dropdown-menu mt-md-5' => $this->isBootstrap4,
+ 'dropdown-menu' => $this->isBootstrap5,
+ ]) }} x-bind:class="{ 'show': filterPopoverOpen }">
@foreach ($this->getVisibleFilters() as $filter)
- $this->isBootstrap,
- ])
- id="{{ $tableName }}-filter-{{ $filter->getKey() }}-wrapper"
- >
+
{{ $filter->setGenericDisplayData($this->getFilterGenericData)->render() }}
@endforeach
@if ($this->hasAppliedVisibleFiltersWithValuesThatCanBeCleared())
-
$this->isBootstrap,
- ])
- >
-
-
-
$this->isBootstrap4,
- 'dropdown-item text-center' => $this->isBootstrap5,
- ])
- >
- {{ __($this->getLocalisationPath.'Clear') }}
-
+
+
@endif
@else
-
- @php /** @var \Rappasoft\LaravelLivewireTables\Views\Filter $filter */ @endphp
+
merge($this->getFilterPopoverAttributes)
+ ->merge([
+ 'role' => 'menu',
+ 'aria-orientation' => 'vertical',
+ 'aria-labelledby' => 'filters-menu',
+ 'x-transition:enter' => 'transition ease-out duration-100',
+ 'x-transition:enter-start' => 'transform opacity-0 scale-95',
+ 'x-transition:enter-end' => 'transform opacity-100 scale-100',
+ 'x-transition:leave' => 'transition ease-in duration-75',
+ 'x-transition:leave-start' => 'transform opacity-100 scale-100',
+ 'x-transition:leave-end' => 'transform opacity-0 scale-95',
+ ])
+ ->class([
+ 'w-full md:w-56' => $this->getFilterPopoverAttributes['default-width'] ?? true,
+ 'origin-top-left absolute left-0 mt-2 rounded-md shadow-lg ring-1 ring-opacity-5 divide-y focus:outline-none z-50' => $this->getFilterPopoverAttributes['default-styling'] ?? true,
+ 'bg-white divide-gray-100 ring-black dark:bg-gray-700 dark:text-white dark:divide-gray-600' => $this->getFilterPopoverAttributes['default-colors'] ?? true,
+ ])
+ ->except(['x-cloak', 'x-show', 'default','default-width', 'default-styling','default-colors'])
+ }}>
+
@foreach ($this->getVisibleFilters() as $filter)
-
+
{{ $filter->setGenericDisplayData($this->getFilterGenericData)->render() }}
@@ -70,15 +53,8 @@ class="block px-4 py-2 text-sm text-gray-700 space-y-1"
@if ($this->hasAppliedVisibleFiltersWithValuesThatCanBeCleared())
-
- {{ __($this->getLocalisationPath.'Clear') }}
-
+
@endif
-@endif
+@endif
\ No newline at end of file
diff --git a/resources/views/components/tools/toolbar/items/filter-popover/clear-button.blade.php b/resources/views/components/tools/toolbar/items/filter-popover/clear-button.blade.php
new file mode 100644
index 000000000..6436cd79f
--- /dev/null
+++ b/resources/views/components/tools/toolbar/items/filter-popover/clear-button.blade.php
@@ -0,0 +1,7 @@
+
$this->isTailwind,
+ 'dropdown-item btn text-center' => $this->isBootstrap4,
+ 'dropdown-item text-center' => $this->isBootstrap5,
+ ])>
+ {{ __($this->getLocalisationPath.'Clear') }}
+
\ No newline at end of file
diff --git a/resources/views/components/tools/toolbar/items/filter-slidedown.blade.php b/resources/views/components/tools/toolbar/items/filter-slidedown.blade.php
index 6692a4e32..be507404b 100644
--- a/resources/views/components/tools/toolbar/items/filter-slidedown.blade.php
+++ b/resources/views/components/tools/toolbar/items/filter-slidedown.blade.php
@@ -1,4 +1,4 @@
-@aware(['component', 'tableName'])
+@aware([ 'tableName'])
@props([])
- @php /** @var \Rappasoft\LaravelLivewireTables\Views\Filter $filter */ @endphp
@foreach ($filterRow as $filter)
$this->isBootstrap4,
'ms-0 ms-md-2' => $this->isBootstrap5,
@@ -6,17 +6,17 @@
>
merge($component->getPerPageFieldAttributes())
+ $attributes->merge($this->getPerPageFieldAttributes())
->class([
- 'form-control' => $this->isBootstrap4 && $component->getPerPageFieldAttributes()['default-styling'],
- 'form-select' => $this->isBootstrap5 && $component->getPerPageFieldAttributes()['default-styling'],
- 'block w-full rounded-md shadow-sm transition duration-150 ease-in-out sm:text-sm sm:leading-5 focus:ring focus:ring-opacity-50' => $this->isTailwind && $component->getPerPageFieldAttributes()['default-styling'],
- 'border-gray-300 focus:border-indigo-300 focus:ring-indigo-200 dark:bg-gray-700 dark:text-white dark:border-gray-600' => $this->isTailwind && $component->getPerPageFieldAttributes()['default-colors'],
+ 'form-control' => $this->isBootstrap4 && $this->getPerPageFieldAttributes()['default-styling'],
+ 'form-select' => $this->isBootstrap5 && $this->getPerPageFieldAttributes()['default-styling'],
+ 'block w-full rounded-md shadow-sm transition duration-150 ease-in-out sm:text-sm sm:leading-5 focus:ring focus:ring-opacity-50' => $this->isTailwind && $this->getPerPageFieldAttributes()['default-styling'],
+ 'border-gray-300 focus:border-indigo-300 focus:ring-indigo-200 dark:bg-gray-700 dark:text-white dark:border-gray-600' => $this->isTailwind && $this->getPerPageFieldAttributes()['default-colors'],
])
->except(['default','default-styling','default-colors'])
}}
>
- @foreach ($component->getPerPageAccepted() as $item)
+ @foreach ($this->getPerPageAccepted() as $item)
$this->isBootstrap4,
diff --git a/resources/views/datatable.blade.php b/resources/views/datatable.blade.php
index 27ef1185f..7b90b7734 100644
--- a/resources/views/datatable.blade.php
+++ b/resources/views/datatable.blade.php
@@ -98,9 +98,9 @@
@foreach($this->selectedVisibleColumns as $colIndex => $column)
@if($column->isHtml())
- {!! $column->renderContents($row) !!}
+ {!! $column->setIndexes($rowIndex, $colIndex)->renderContents($row) !!}
@else
- {{ $column->renderContents($row) }}
+ {{ $column->setIndexes($rowIndex, $colIndex)->renderContents($row) }}
@endif
@endforeach
diff --git a/resources/views/includes/actions/button.blade.php b/resources/views/includes/actions/button.blade.php
index f142502d2..074a36de2 100644
--- a/resources/views/includes/actions/button.blade.php
+++ b/resources/views/includes/actions/button.blade.php
@@ -1,4 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Action $action */ @endphp
merge()
->class(['justify-center text-center items-center inline-flex space-x-2 rounded-md border shadow-sm px-4 py-2 text-sm font-medium focus:ring focus:ring-opacity-50' => $isTailwind && $attributes['default-styling'] ?? true])
->class(['focus:border-indigo-300 focus:ring-indigo-200' => $isTailwind && $attributes['default-colors'] ?? true])
diff --git a/resources/views/includes/columns/increment.blade.php b/resources/views/includes/columns/increment.blade.php
new file mode 100644
index 000000000..5ede69f09
--- /dev/null
+++ b/resources/views/includes/columns/increment.blade.php
@@ -0,0 +1,2 @@
+@aware(['rowIndex'])
+{{ $rowIndex+1 }}
diff --git a/resources/views/includes/columns/link.blade.php b/resources/views/includes/columns/link.blade.php
index a2f350d28..e361ae7f5 100644
--- a/resources/views/includes/columns/link.blade.php
+++ b/resources/views/includes/columns/link.blade.php
@@ -1,5 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Columns\LinkColumn $column */ @endphp
-
arrayToAttributes($attributes) : '' !!}>
@if($column->isHtml())
{!! $title !!}
diff --git a/resources/views/includes/columns/wire-link.blade.php b/resources/views/includes/columns/wire-link.blade.php
index 6770e3936..dc8add95c 100644
--- a/resources/views/includes/columns/wire-link.blade.php
+++ b/resources/views/includes/columns/wire-link.blade.php
@@ -1,4 +1,3 @@
-@php /** @var \Rappasoft\LaravelLivewireTables\Views\Columns\WireLinkColumn $column */ @endphp
arrayToAttributes($attributes) : '' !!}
@if($column->hasConfirmMessage())
diff --git a/src/Traits/Configuration/FilterConfiguration.php b/src/Traits/Configuration/FilterConfiguration.php
index 5f8a0629f..d17e7bf16 100644
--- a/src/Traits/Configuration/FilterConfiguration.php
+++ b/src/Traits/Configuration/FilterConfiguration.php
@@ -3,7 +3,6 @@
namespace Rappasoft\LaravelLivewireTables\Traits\Configuration;
use Rappasoft\LaravelLivewireTables\DataTransferObjects\FilterGenericData;
-use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
trait FilterConfiguration
{
@@ -70,52 +69,6 @@ public function setFilterPillsDisabled(): self
return $this;
}
- public function setFilterLayout(string $type): self
- {
- if (! in_array($type, ['popover', 'slide-down'], true)) {
- throw new DataTableConfigurationException('Invalid filter layout type');
- }
-
- $this->filterLayout = $type;
-
- return $this;
- }
-
- public function setFilterLayoutPopover(): self
- {
- $this->setFilterLayout('popover');
-
- return $this;
- }
-
- public function setFilterLayoutSlideDown(): self
- {
- $this->setFilterLayout('slide-down');
-
- return $this;
- }
-
- public function setFilterSlideDownDefaultStatus(bool $status): self
- {
- $this->filterSlideDownDefaultVisible = $status;
-
- return $this;
- }
-
- public function setFilterSlideDownDefaultStatusDisabled(): self
- {
- $this->setFilterSlideDownDefaultStatus(false);
-
- return $this;
- }
-
- public function setFilterSlideDownDefaultStatusEnabled(): self
- {
- $this->setFilterSlideDownDefaultStatus(true);
-
- return $this;
- }
-
public function generateFilterGenericData(): array
{
return (new FilterGenericData($this->getTableName(), $this->getFilterLayout(), $this->isTailwind(), $this->isBootstrap4(), $this->isBootstrap5()))->toArray();
diff --git a/src/Traits/Helpers/FilterHelpers.php b/src/Traits/Helpers/FilterHelpers.php
index c42fdeac2..2ee7ed3db 100644
--- a/src/Traits/Helpers/FilterHelpers.php
+++ b/src/Traits/Helpers/FilterHelpers.php
@@ -63,21 +63,6 @@ public function filtersVisibilityIsDisabled(): bool
return $this->getFiltersVisibilityStatus() === false;
}
- public function getFilterSlideDownDefaultStatus(): bool
- {
- return $this->filterSlideDownDefaultVisible;
- }
-
- public function filtersSlideDownIsDefaultVisible(): bool
- {
- return $this->getFilterSlideDownDefaultStatus() === true;
- }
-
- public function filtersSlideDownIsDefaultHidden(): bool
- {
- return $this->getFilterSlideDownDefaultStatus() === false;
- }
-
public function getFilterPillsStatus(): bool
{
return $this->filterPillsStatus;
@@ -273,31 +258,6 @@ public function resetFilter($filter): void
}
- public function getFilterLayout(): string
- {
- return $this->filterLayout;
- }
-
- public function isFilterLayoutPopover(): bool
- {
- return $this->getFilterLayout() === 'popover';
- }
-
- public function isFilterLayoutSlideDown(): bool
- {
- return $this->getFilterLayout() === 'slide-down';
- }
-
- /**
- * Get whether any filter has a configured slide down row.
- */
- public function hasFiltersWithSlidedownRows(): bool
- {
- return $this->getFilters()
- ->reject(fn (Filter $filter) => ! $filter->hasFilterSlidedownRow())
- ->count() > 0;
- }
-
/**
* Get whether filter has a configured slide down row.
*/
@@ -306,38 +266,6 @@ public function getVisibleFilters(): Collection
return $this->getFilters()->reject(fn (Filter $filter) => $filter->isHiddenFromMenus());
}
- /**
- * Get filters sorted by row
- *
- * @return array
- */
- public function getFiltersByRow(): array
- {
- $orderedFilters = [];
- $filterList = ($this->hasFiltersWithSlidedownRows()) ? $this->getVisibleFilters()->sortBy('filterSlidedownRow') : $this->getVisibleFilters();
- if ($this->hasFiltersWithSlidedownRows()) {
- foreach ($filterList as $filter) {
- $orderedFilters[(string) $filter->getFilterSlidedownRow()][] = $filter;
- }
-
- if (empty($orderedFilters['1'])) {
- $orderedFilters['1'] = (isset($orderedFilters['99']) ? $orderedFilters['99'] : []);
- if (isset($orderedFilters['99'])) {
- unset($orderedFilters['99']);
- }
- }
- } else {
- $orderedFilters = Arr::wrap($filterList);
- $orderedFilters['1'] = $orderedFilters['0'] ?? [];
- if (isset($orderedFilters['0'])) {
- unset($orderedFilters['0']);
- }
- }
- ksort($orderedFilters);
-
- return $orderedFilters;
- }
-
public function hasFilterGenericData(): bool
{
return ! empty($this->filterGenericData);
diff --git a/src/Traits/Styling/Configuration/FilterMenuStylingConfiguration.php b/src/Traits/Styling/Configuration/FilterMenuStylingConfiguration.php
new file mode 100644
index 000000000..92d8ba467
--- /dev/null
+++ b/src/Traits/Styling/Configuration/FilterMenuStylingConfiguration.php
@@ -0,0 +1,64 @@
+filterPopoverAttributes = array_merge($this->filterPopoverAttributes, $filterPopoverAttributes);
+
+ return $this;
+ }
+
+ public function setFilterLayout(string $type): self
+ {
+ if (! in_array($type, ['popover', 'slide-down'], true)) {
+ throw new DataTableConfigurationException('Invalid filter layout type');
+ }
+
+ $this->filterLayout = $type;
+
+ return $this;
+ }
+
+ public function setFilterLayoutPopover(): self
+ {
+ $this->setFilterLayout('popover');
+
+ return $this;
+ }
+
+ public function setFilterLayoutSlideDown(): self
+ {
+ $this->setFilterLayout('slide-down');
+
+ return $this;
+ }
+
+ public function setFilterSlideDownDefaultStatus(bool $status): self
+ {
+ $this->filterSlideDownDefaultVisible = $status;
+
+ return $this;
+ }
+
+ public function setFilterSlideDownDefaultStatusDisabled(): self
+ {
+ $this->setFilterSlideDownDefaultStatus(false);
+
+ return $this;
+ }
+
+ public function setFilterSlideDownDefaultStatusEnabled(): self
+ {
+ $this->setFilterSlideDownDefaultStatus(true);
+
+ return $this;
+ }
+}
diff --git a/src/Traits/Styling/HasFilterMenuStyling.php b/src/Traits/Styling/HasFilterMenuStyling.php
new file mode 100644
index 000000000..c534027e4
--- /dev/null
+++ b/src/Traits/Styling/HasFilterMenuStyling.php
@@ -0,0 +1,21 @@
+ '', 'default-width' => true, 'default-colors' => true, 'default-styling' => true];
+}
diff --git a/src/Traits/Styling/Helpers/FilterMenuStylingHelpers.php b/src/Traits/Styling/Helpers/FilterMenuStylingHelpers.php
new file mode 100644
index 000000000..d5ddf6d6c
--- /dev/null
+++ b/src/Traits/Styling/Helpers/FilterMenuStylingHelpers.php
@@ -0,0 +1,94 @@
+
+ */
+ #[Computed]
+ public function getFilterPopoverAttributes(): array
+ {
+ return $this->filterPopoverAttributes;
+
+ }
+
+ public function getFilterSlideDownDefaultStatus(): bool
+ {
+ return $this->filterSlideDownDefaultVisible;
+ }
+
+ public function filtersSlideDownIsDefaultVisible(): bool
+ {
+ return $this->getFilterSlideDownDefaultStatus() === true;
+ }
+
+ public function filtersSlideDownIsDefaultHidden(): bool
+ {
+ return $this->getFilterSlideDownDefaultStatus() === false;
+ }
+
+ public function getFilterLayout(): string
+ {
+ return $this->filterLayout;
+ }
+
+ public function isFilterLayoutPopover(): bool
+ {
+ return $this->getFilterLayout() === 'popover';
+ }
+
+ public function isFilterLayoutSlideDown(): bool
+ {
+ return $this->getFilterLayout() === 'slide-down';
+ }
+
+ /**
+ * Get whether any filter has a configured slide down row.
+ */
+ public function hasFiltersWithSlidedownRows(): bool
+ {
+ return $this->getFilters()
+ ->reject(fn (Filter $filter) => ! $filter->hasFilterSlidedownRow())
+ ->count() > 0;
+ }
+
+ /**
+ * Get filters sorted by row
+ *
+ * @return array
+ */
+ public function getFiltersByRow(): array
+ {
+ $orderedFilters = [];
+ $filterList = ($this->hasFiltersWithSlidedownRows()) ? $this->getVisibleFilters()->sortBy('filterSlidedownRow') : $this->getVisibleFilters();
+ if ($this->hasFiltersWithSlidedownRows()) {
+ foreach ($filterList as $filter) {
+ $orderedFilters[(string) $filter->getFilterSlidedownRow()][] = $filter;
+ }
+
+ if (empty($orderedFilters['1'])) {
+ $orderedFilters['1'] = (isset($orderedFilters['99']) ? $orderedFilters['99'] : []);
+ if (isset($orderedFilters['99'])) {
+ unset($orderedFilters['99']);
+ }
+ }
+ } else {
+ $orderedFilters = Arr::wrap($filterList);
+ $orderedFilters['1'] = $orderedFilters['0'] ?? [];
+ if (isset($orderedFilters['0'])) {
+ unset($orderedFilters['0']);
+ }
+ }
+ ksort($orderedFilters);
+
+ return $orderedFilters;
+ }
+}
diff --git a/src/Traits/WithEvents.php b/src/Traits/WithEvents.php
index 79a14c77c..ab510200b 100644
--- a/src/Traits/WithEvents.php
+++ b/src/Traits/WithEvents.php
@@ -13,24 +13,36 @@ trait WithEvents
protected array $eventStatuses = ['columnSelected' => true, 'searchApplied' => false, 'filterApplied' => false];
// No Longer Used
+ /**
+ * @codeCoverageIgnore
+ */
public function setSortEvent(string $field, string $direction): void
{
$this->setSort($field, $direction);
}
// No Longer Used
+ /**
+ * @codeCoverageIgnore
+ */
public function clearSortEvent(): void
{
$this->clearSorts();
}
// No Longer Used
+ /**
+ * @codeCoverageIgnore
+ */
public function setFilterEvent(string $filter, string|array|null $value): void
{
$this->setFilter($filter, $value);
}
// No Longer Used
+ /**
+ * @codeCoverageIgnore
+ */
public function clearFilterEvent(): void
{
$this->setFilterDefaults();
diff --git a/src/Traits/WithFilters.php b/src/Traits/WithFilters.php
index e9469ea44..140ae6d0b 100644
--- a/src/Traits/WithFilters.php
+++ b/src/Traits/WithFilters.php
@@ -9,12 +9,14 @@
use Rappasoft\LaravelLivewireTables\Traits\Configuration\FilterConfiguration;
use Rappasoft\LaravelLivewireTables\Traits\Core\QueryStrings\HasQueryStringForFilter;
use Rappasoft\LaravelLivewireTables\Traits\Helpers\FilterHelpers;
+use Rappasoft\LaravelLivewireTables\Traits\Styling\HasFilterMenuStyling;
trait WithFilters
{
use FilterConfiguration,
FilterHelpers;
use HasQueryStringForFilter;
+ use HasFilterMenuStyling;
#[Locked]
public bool $filtersStatus = true;
@@ -25,12 +27,6 @@ trait WithFilters
#[Locked]
public bool $filterPillsStatus = true;
- // Entangled in JS
- public bool $filterSlideDownDefaultVisible = false;
-
- #[Locked]
- public string $filterLayout = 'popover';
-
#[Locked]
public int $filterCount;
diff --git a/src/Views/Columns/IncrementColumn.php b/src/Views/Columns/IncrementColumn.php
new file mode 100644
index 000000000..4271fe721
--- /dev/null
+++ b/src/Views/Columns/IncrementColumn.php
@@ -0,0 +1,26 @@
+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
+ {
+ return view($this->getView())
+ ->withColumn($this)
+ ->withAttributeBag($this->getAttributeBag($row));
+ }
+}
diff --git a/src/Views/Traits/Configuration/ColumnConfiguration.php b/src/Views/Traits/Configuration/ColumnConfiguration.php
index c46b01663..0115e74fe 100644
--- a/src/Views/Traits/Configuration/ColumnConfiguration.php
+++ b/src/Views/Traits/Configuration/ColumnConfiguration.php
@@ -97,4 +97,26 @@ public function setIsReorderColumn(bool $isReorderColumn): self
return $this;
}
+
+ public function setIndexes(int $rowIndex, int $columnIndex): self
+ {
+ $this->setRowIndex($rowIndex);
+ $this->setColumnIndex($columnIndex);
+
+ return $this;
+ }
+
+ public function setColumnIndex(int $columnIndex): self
+ {
+ $this->columnIndex = $columnIndex;
+
+ return $this;
+ }
+
+ public function setRowIndex(int $rowIndex): self
+ {
+ $this->rowIndex = $rowIndex;
+
+ return $this;
+ }
}
diff --git a/src/Views/Traits/Helpers/ColumnHelpers.php b/src/Views/Traits/Helpers/ColumnHelpers.php
index da220287e..164de98da 100644
--- a/src/Views/Traits/Helpers/ColumnHelpers.php
+++ b/src/Views/Traits/Helpers/ColumnHelpers.php
@@ -215,4 +215,14 @@ public function getIsReorderColumn(): bool
{
return $this->isReorderColumn;
}
+
+ public function getColumnIndex(): int
+ {
+ return $this->columnIndex;
+ }
+
+ public function getRowIndex(): int
+ {
+ return $this->rowIndex;
+ }
}
diff --git a/src/Views/Traits/IsColumn.php b/src/Views/Traits/IsColumn.php
index b90a8b2e4..d36b3e06d 100644
--- a/src/Views/Traits/IsColumn.php
+++ b/src/Views/Traits/IsColumn.php
@@ -62,4 +62,8 @@ trait IsColumn
protected bool $hasTableRowUrl = false;
protected bool $isReorderColumn = false;
+
+ protected ?int $columnIndex;
+
+ protected ?int $rowIndex;
}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 957aa151f..eb5f3b441 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -103,7 +103,13 @@ protected function setupBasicTable()
$this->basicTable->bootedWithColumnSelect();
$this->basicTable->bootedWithSecondaryHeader();
$this->basicTable->booted();
- $this->basicTable->renderingWithPagination($view, []);
+ $this->basicTable->renderingWithColumns($view, $view->getData());
+ $this->basicTable->renderingWithColumnSelect($view, $view->getData());
+ $this->basicTable->renderingWithCustomisations($view, $view->getData());
+ $this->basicTable->renderingWithData($view, $view->getData());
+ $this->basicTable->renderingWithFooter($view, $view->getData());
+ $this->basicTable->renderingWithReordering($view, $view->getData());
+ $this->basicTable->renderingWithPagination($view, $view->getData());
$this->basicTable->render();
}
@@ -118,7 +124,14 @@ protected function setupEventsTable()
$this->eventsTable->bootedWithColumnSelect();
$this->eventsTable->bootedWithSecondaryHeader();
$this->eventsTable->booted();
- $this->eventsTable->renderingWithPagination($view, []);
+ $this->eventsTable->renderingWithColumns($view, $view->getData());
+ $this->eventsTable->renderingWithColumnSelect($view, $view->getData());
+ $this->eventsTable->renderingWithCustomisations($view, $view->getData());
+ $this->eventsTable->renderingWithData($view, $view->getData());
+ $this->eventsTable->renderingWithFooter($view, $view->getData());
+ $this->eventsTable->renderingWithReordering($view, $view->getData());
+ $this->eventsTable->renderingWithPagination($view, $view->getData());
+
$this->eventsTable->render();
}
@@ -133,7 +146,13 @@ protected function setupBreedsTable()
$this->breedsTable->bootedWithColumnSelect();
$this->breedsTable->bootedWithSecondaryHeader();
$this->breedsTable->booted();
- $this->breedsTable->renderingWithPagination($view, []);
+ $this->breedsTable->renderingWithColumns($view, $view->getData());
+ $this->breedsTable->renderingWithColumnSelect($view, $view->getData());
+ $this->breedsTable->renderingWithCustomisations($view, $view->getData());
+ $this->breedsTable->renderingWithData($view, $view->getData());
+ $this->breedsTable->renderingWithFooter($view, $view->getData());
+ $this->breedsTable->renderingWithReordering($view, $view->getData());
+ $this->breedsTable->renderingWithPagination($view, $view->getData());
$this->breedsTable->render();
}
@@ -148,7 +167,13 @@ protected function setupPetOwnerTable()
$this->petOwnerTable->bootedWithColumnSelect();
$this->petOwnerTable->bootedWithSecondaryHeader();
$this->petOwnerTable->booted();
- $this->petOwnerTable->renderingWithPagination($view, []);
+ $this->petOwnerTable->renderingWithColumns($view, $view->getData());
+ $this->petOwnerTable->renderingWithColumnSelect($view, $view->getData());
+ $this->petOwnerTable->renderingWithCustomisations($view, $view->getData());
+ $this->petOwnerTable->renderingWithData($view, $view->getData());
+ $this->petOwnerTable->renderingWithFooter($view, $view->getData());
+ $this->petOwnerTable->renderingWithReordering($view, $view->getData());
+ $this->petOwnerTable->renderingWithPagination($view, $view->getData());
$this->petOwnerTable->render();
}
@@ -163,7 +188,13 @@ protected function setupSpeciesTable()
$this->speciesTable->bootedWithColumnSelect();
$this->speciesTable->bootedWithSecondaryHeader();
$this->speciesTable->booted();
- $this->speciesTable->renderingWithPagination($view, []);
+ $this->speciesTable->renderingWithColumns($view, $view->getData());
+ $this->speciesTable->renderingWithColumnSelect($view, $view->getData());
+ $this->speciesTable->renderingWithCustomisations($view, $view->getData());
+ $this->speciesTable->renderingWithData($view, $view->getData());
+ $this->speciesTable->renderingWithFooter($view, $view->getData());
+ $this->speciesTable->renderingWithReordering($view, $view->getData());
+ $this->speciesTable->renderingWithPagination($view, $view->getData());
$this->speciesTable->render();
}
@@ -179,7 +210,13 @@ protected function setupUnpaginatedTable()
$this->unpaginatedTable->bootedWithColumnSelect();
$this->unpaginatedTable->bootedWithSecondaryHeader();
$this->unpaginatedTable->booted();
- $this->unpaginatedTable->renderingWithPagination($view, []);
+ $this->unpaginatedTable->renderingWithColumns($view, $view->getData());
+ $this->unpaginatedTable->renderingWithColumnSelect($view, $view->getData());
+ $this->unpaginatedTable->renderingWithCustomisations($view, $view->getData());
+ $this->unpaginatedTable->renderingWithData($view, $view->getData());
+ $this->unpaginatedTable->renderingWithFooter($view, $view->getData());
+ $this->unpaginatedTable->renderingWithReordering($view, $view->getData());
+ $this->unpaginatedTable->renderingWithPagination($view, $view->getData());
$this->unpaginatedTable->render();
}
@@ -202,6 +239,10 @@ public function getEnvironmentSetUp($app): void
config()->set('view.cache', false);
config()->set('view.compiled', realpath(storage_path('framework/views')).'/'.rand(0, 100));
// config()->set('livewire-tables.use_json_translations', true);
+ $app['config']->set('view.paths', [
+ __DIR__.'/views',
+ resource_path('views'),
+ ]);
$app['config']->set('app.env', 'testing');
$app['config']->set('database.default', 'sqlite');
diff --git a/tests/Unit/Traits/Configuration/SearchConfigurationTest.php b/tests/Unit/Traits/Configuration/SearchConfigurationTest.php
index cc55f8362..6b6635533 100644
--- a/tests/Unit/Traits/Configuration/SearchConfigurationTest.php
+++ b/tests/Unit/Traits/Configuration/SearchConfigurationTest.php
@@ -96,23 +96,23 @@ public function test_cant_set_search_defer_with_other_search_modifiers(): void
$this->basicTable->setSearchDebounce(1000);
}
- /*public function test_can_set_search_lazy(): void
+ public function test_can_set_search_lazy(): void
{
$this->assertFalse($this->basicTable->hasSearchLazy());
$this->basicTable->setSearchLazy();
$this->assertTrue($this->basicTable->hasSearchLazy());
- $this->assertSame('.lazy', $this->basicTable->getSearchOptions());
- }*/
+ $this->assertSame('.live.lazy', $this->basicTable->getSearchOptions());
+ }
- /*public function test_cant_set_search_lazy_with_other_search_modifiers(): void
+ public function test_cant_set_search_lazy_with_other_search_modifiers(): void
{
$this->expectException(DataTableConfigurationException::class);
$this->basicTable->setSearchLazy();
$this->basicTable->setSearchDebounce(1000);
- }*/
+ }
public function test_can_set_search_live(): void
{
diff --git a/tests/Unit/Traits/Helpers/SearchHelpersTest.php b/tests/Unit/Traits/Helpers/SearchHelpersTest.php
index f2d58597c..b04d8fed8 100644
--- a/tests/Unit/Traits/Helpers/SearchHelpersTest.php
+++ b/tests/Unit/Traits/Helpers/SearchHelpersTest.php
@@ -2,6 +2,7 @@
namespace Rappasoft\LaravelLivewireTables\Tests\Unit\Traits\Helpers;
+use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\PetsTable;
use Rappasoft\LaravelLivewireTables\Tests\TestCase;
final class SearchHelpersTest extends TestCase
@@ -86,14 +87,14 @@ public function test_can_check_if_search_blur_is_set(): void
$this->assertTrue($this->basicTable->hasSearchBlur());
}
- /*public function test_can_check_if_search_lazy_is_set(): void
+ public function test_can_check_if_search_lazy_is_set(): void
{
$this->assertFalse($this->basicTable->hasSearchLazy());
$this->basicTable->setSearchLazy();
$this->assertTrue($this->basicTable->hasSearchLazy());
- }*/
+ }
public function test_can_check_if_search_throttle_is_set(): void
{
@@ -148,4 +149,49 @@ public function test_can_trim_whitespace_from_search(): void
$this->assertSame(' Anthony ', $this->basicTable->getSearch());
}
+
+ public function test_can_test_all_search_options(): void
+ {
+ $temp = new class extends PetsTable
+ {
+ public function resetSearchConfiguration(): self
+ {
+ $this->searchFilterBlur = null;
+ $this->searchFilterDebounce = null;
+ $this->searchFilterDefer = null;
+ $this->searchFilterLazy = null;
+ $this->searchFilterLive = null;
+ $this->searchFilterThrottle = null;
+
+ return $this;
+ }
+ };
+
+ $this->assertFalse($temp->hasSearchDebounce());
+
+ $temp->setSearchDebounce(1000);
+
+ $this->assertSame('.live.debounce.1000ms', $temp->getSearchOptions());
+
+ $temp->resetSearchConfiguration()->setSearchDefer();
+
+ $this->assertSame('', $temp->getSearchOptions());
+
+ $temp->resetSearchConfiguration()->setSearchLive();
+
+ $this->assertSame('.live', $temp->getSearchOptions());
+
+ $temp->resetSearchConfiguration()->setSearchBlur();
+
+ $this->assertSame('.blur', $temp->getSearchOptions());
+
+ $temp->resetSearchConfiguration()->setSearchLazy();
+
+ $this->assertSame('.live.lazy', $temp->getSearchOptions());
+
+ $temp->resetSearchConfiguration()->setSearchThrottle(599);
+
+ $this->assertSame('.live.throttle.599ms', $temp->getSearchOptions());
+
+ }
}
diff --git a/tests/Unit/Traits/Styling/FilterPopoverStylingTest.php b/tests/Unit/Traits/Styling/FilterPopoverStylingTest.php
new file mode 100644
index 000000000..886ae1956
--- /dev/null
+++ b/tests/Unit/Traits/Styling/FilterPopoverStylingTest.php
@@ -0,0 +1,27 @@
+assertSame(['class' => '', 'default-width' => true, 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPopoverAttributes());
+ }
+
+ public function test_filter_popover_attributes_can_be_changed(): void
+ {
+ $this->assertSame(['class' => '', 'default-width' => true, 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPopoverAttributes());
+
+ $this->basicTable->setFilterPopoverAttributes(['class' => 'bg-blue-500']);
+
+ $this->assertSame(['class' => 'bg-blue-500', 'default-width' => true, 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPopoverAttributes());
+
+ $this->basicTable->setFilterPopoverAttributes(['class' => 'bg-red-500', 'default-colors' => false]);
+
+ $this->assertSame(['class' => 'bg-red-500', 'default-width' => true, 'default-colors' => false, 'default-styling' => true], $this->basicTable->getFilterPopoverAttributes());
+
+ }
+}
diff --git a/tests/Unit/Traits/Visuals/FilterVisualsTest.php b/tests/Unit/Traits/Visuals/FilterVisualsTest.php
index 09b27ab9c..d55a00cb0 100644
--- a/tests/Unit/Traits/Visuals/FilterVisualsTest.php
+++ b/tests/Unit/Traits/Visuals/FilterVisualsTest.php
@@ -161,6 +161,66 @@ public function filters(): array
]);
}
+ public function test_filters_popover_menu_is_customisable(): void
+ {
+ Livewire::test(new class extends PetsTable
+ {
+ public function configure(): void
+ {
+ $this->setPrimaryKey('id');
+
+ }
+
+ public function filters(): array
+ {
+ return [
+ \Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectFilter::make('Breed')
+ ->options(
+ \Rappasoft\LaravelLivewireTables\Tests\Models\Breed::query()
+ ->orderBy('name')
+ ->get()
+ ->keyBy('id')
+ ->map(fn ($breed) => $breed->name)
+ ->toArray()
+ )
+ ->filter(function (\Illuminate\Database\Eloquent\Builder $builder, array $values) {
+ return $builder->whereIn('pets.breed_id', $values);
+ }),
+ \Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectDropdownFilter::make('Species')
+ ->options(
+ \Rappasoft\LaravelLivewireTables\Tests\Models\Species::query()
+ ->orderBy('name')
+ ->get()
+ ->keyBy('id')
+ ->map(fn ($species) => $species->name)
+ ->toArray()
+ )
+ ->filter(function (\Illuminate\Database\Eloquent\Builder $builder, array $values) {
+ return $builder->whereIn('pets.species_id', $values);
+ })
+ ->setPillsSeparator(' '),
+
+ \Rappasoft\LaravelLivewireTables\Views\Filters\TextFilter::make('Pet Name', 'pet_name_filter')
+ ->filter(function (\Illuminate\Database\Eloquent\Builder $builder, string $value) {
+ return $builder->where('pets.name', '=', $value);
+ }),
+ ];
+ }
+ })
+ ->assertSeeHtmlInOrder([
+ 'class="w-full md:w-56 origin-top-left absolute left-0 mt-2 rounded-md shadow-lg ring-1 ring-opacity-5 divide-y focus:outline-none z-50 bg-white divide-gray-100 ring-black dark:bg-gray-700 dark:text-white dark:divide-gray-600"',
+ ])
+ ->call('setFilterPopoverAttributes', ['class' => 'w-96', 'default-width' => false])
+ ->assertSeeHtmlInOrder([
+ 'class="origin-top-left absolute left-0 mt-2 rounded-md shadow-lg ring-1 ring-opacity-5 divide-y focus:outline-none z-50 bg-white divide-gray-100 ring-black dark:bg-gray-700 dark:text-white dark:divide-gray-600 w-96"',
+ ])
+ ->call('setFilterPopoverAttributes', ['class' => 'w-96', 'default-width' => false, 'default-colors' => false])
+ ->assertSeeHtmlInOrder([
+ 'class="origin-top-left absolute left-0 mt-2 rounded-md shadow-lg ring-1 ring-opacity-5 divide-y focus:outline-none z-50 w-96"',
+ ]);
+
+ }
+
/*public function test_filter_events_apply_correctly(): void
{
Livewire::test(PetsTable::class)
diff --git a/tests/Unit/Traits/Visuals/SearchVisualsTest.php b/tests/Unit/Traits/Visuals/SearchVisualsTest.php
index d951d9b6f..c64876e32 100644
--- a/tests/Unit/Traits/Visuals/SearchVisualsTest.php
+++ b/tests/Unit/Traits/Visuals/SearchVisualsTest.php
@@ -62,6 +62,14 @@ public function test_search_blur_filter_is_applied(): void
->assertSeeHtml('wire:model.blur="search"');
}
+ public function test_search_lazy_filter_is_applied(): void
+ {
+ Livewire::test(PetsTable::class)
+ ->assertDontSeeHtml('wire:model.live.lazy="search"')
+ ->call('setSearchLazy')
+ ->assertSeeHtml('wire:model.live.lazy="search"');
+ }
+
public function test_search_defer_filter_is_applied(): void
{
Livewire::test(PetsTable::class)
@@ -72,7 +80,8 @@ public function test_search_defer_filter_is_applied(): void
public function test_search_live_filter_is_applied(): void
{
Livewire::test(PetsTable::class)
- ->assertDontSeeHtml('wire:model="search"')
+ ->call('setSearchLazy')
+ ->assertDontSeeHtml('wire:model.live="search"')
->call('setSearchLive')
->assertSeeHtml('wire:model.live="search"');
}
diff --git a/tests/Unit/Traits/WithCustomisationsTest.php b/tests/Unit/Traits/WithCustomisationsTest.php
new file mode 100644
index 000000000..64ccf4d36
--- /dev/null
+++ b/tests/Unit/Traits/WithCustomisationsTest.php
@@ -0,0 +1,178 @@
+
+ ParentComponentTest
+
+
+ HTML;
+ }
+ },
+ 'child' => new class extends PetsTable
+ {
+ public function configure(): void
+ {
+ parent::configure();
+ $this->setLayout('livewire-tables::tests.layout1');
+
+ }
+ },
+ ])
+ ->assertSee('ParentComponentTest')
+ ->assertSee('Cartman');
+
+ }
+
+ public function test_can_use_as_full_page(): void
+ {
+ $temp = new class extends PetsTable
+ {
+ public function configure(): void
+ {
+ parent::configure();
+
+ $this->setLayout('livewire-tables::tests.layout1');
+
+ }
+ };
+ $view = view('livewire-tables::datatable');
+
+ $temp->boot();
+ $temp->bootedComponentUtilities();
+ $temp->bootedWithData();
+ $temp->bootedWithColumns();
+ $temp->bootedWithColumnSelect();
+ $temp->bootedWithSecondaryHeader();
+ $temp->booted();
+ $temp->renderingWithColumns($view, $view->getData());
+ $temp->renderingWithColumnSelect($view, $view->getData());
+ $temp->renderingWithCustomisations($view, $view->getData());
+ $temp->renderingWithData($view, $view->getData());
+ $temp->renderingWithFooter($view, $view->getData());
+ $temp->renderingWithReordering($view, $view->getData());
+ $temp->renderingWithPagination($view, $view->getData());
+ $temp->render();
+ $layoutConfig = $view->getData()['layoutConfig'];
+
+ $this->assertSame($temp->getLayout(), $layoutConfig->view);
+ }
+
+ public function test_can_set_custom_section(): void
+ {
+ $temp = new class extends PetsTable
+ {
+ public function configure(): void
+ {
+ parent::configure();
+
+ $this->setSection('test-section-1');
+
+ }
+ };
+ $view = view('livewire-tables::datatable');
+
+ $temp->boot();
+ $temp->bootedComponentUtilities();
+ $temp->bootedWithData();
+ $temp->bootedWithColumns();
+ $temp->bootedWithColumnSelect();
+ $temp->bootedWithSecondaryHeader();
+ $temp->booted();
+ $temp->renderingWithColumns($view, $view->getData());
+ $temp->renderingWithColumnSelect($view, $view->getData());
+ $temp->renderingWithCustomisations($view, $view->getData());
+ $temp->renderingWithData($view, $view->getData());
+ $temp->renderingWithFooter($view, $view->getData());
+ $temp->renderingWithReordering($view, $view->getData());
+ $temp->renderingWithPagination($view, $view->getData());
+ $temp->render();
+ $layoutConfig = $view->getData()['layoutConfig'];
+
+ $this->assertSame($temp->getSection(), $layoutConfig->slotOrSection);
+ }
+
+ public function test_can_set_custom_slot(): void
+ {
+ $temp = new class extends PetsTable
+ {
+ public function configure(): void
+ {
+ parent::configure();
+
+ $this->setSlot('test-slot-1');
+
+ }
+ };
+ $view = view('livewire-tables::datatable');
+
+ $temp->boot();
+ $temp->bootedComponentUtilities();
+ $temp->bootedWithData();
+ $temp->bootedWithColumns();
+ $temp->bootedWithColumnSelect();
+ $temp->bootedWithSecondaryHeader();
+ $temp->booted();
+ $temp->renderingWithColumns($view, $view->getData());
+ $temp->renderingWithColumnSelect($view, $view->getData());
+ $temp->renderingWithCustomisations($view, $view->getData());
+ $temp->renderingWithData($view, $view->getData());
+ $temp->renderingWithFooter($view, $view->getData());
+ $temp->renderingWithReordering($view, $view->getData());
+ $temp->renderingWithPagination($view, $view->getData());
+ $temp->render();
+ $layoutConfig = $view->getData()['layoutConfig'];
+
+ $this->assertSame($temp->getSlot(), $layoutConfig->slotOrSection);
+ }
+
+ public function test_can_set_custom_extends(): void
+ {
+ $temp = new class extends PetsTable
+ {
+ public function configure(): void
+ {
+ parent::configure();
+
+ $this->setExtends('test-extends-1');
+
+ }
+ };
+ $view = view('livewire-tables::datatable');
+
+ $temp->boot();
+ $temp->bootedComponentUtilities();
+ $temp->bootedWithData();
+ $temp->bootedWithColumns();
+ $temp->bootedWithColumnSelect();
+ $temp->bootedWithSecondaryHeader();
+ $temp->booted();
+ $temp->renderingWithColumns($view, $view->getData());
+ $temp->renderingWithColumnSelect($view, $view->getData());
+ $temp->renderingWithCustomisations($view, $view->getData());
+ $temp->renderingWithData($view, $view->getData());
+ $temp->renderingWithFooter($view, $view->getData());
+ $temp->renderingWithReordering($view, $view->getData());
+ $temp->renderingWithPagination($view, $view->getData());
+ $temp->render();
+ $layoutConfig = $view->getData()['layoutConfig'];
+ $this->assertSame('extends', $layoutConfig->type);
+ $this->assertSame($temp->getExtends(), $layoutConfig->view);
+ $this->assertSame('content', $layoutConfig->slotOrSection);
+ }
+}
diff --git a/tests/Unit/Views/Columns/IncrementColumnTest.php b/tests/Unit/Views/Columns/IncrementColumnTest.php
new file mode 100644
index 000000000..88302d164
--- /dev/null
+++ b/tests/Unit/Views/Columns/IncrementColumnTest.php
@@ -0,0 +1,73 @@
+assertSame('Name', $column->getTitle());
+ }
+
+ public function test_can_not_infer_field_name_from_title_if_no_from(): void
+ {
+ $column = IncrementColumn::make('My Title');
+
+ $this->assertNull($column->getField());
+ }
+
+ public function test_can_not_render_field_if_no_title(): void
+ {
+ $this->expectException(\ArgumentCountError::class);
+
+ IncrementColumn::make()->getContents(Pet::find(1));
+ }
+
+ public function test_handles_row_index_correctly(): void
+ {
+ $rows = $this->basicTable->getRows();
+ $row1 = $rows->first();
+ $col = IncrementColumn::make('#')->setRowIndex(1);
+ $contents = $col->getContents($row1);
+ $this->assertSame(1, $col->getRowIndex());
+
+ }
+
+ public function test_handles_col_index_correctly(): void
+ {
+ $rows = $this->basicTable->getRows();
+ $row1 = $rows->first();
+ $col = IncrementColumn::make('#')->setColumnIndex(2);
+ $contents = $col->getContents($row1);
+ $this->assertSame(2, $col->getColumnIndex());
+
+ }
+
+ public function test_handles_indexes_correctly(): void
+ {
+ $rows = $this->basicTable->getRows();
+ $row1 = $rows->first();
+ $col = IncrementColumn::make('#')->setIndexes(5, 3);
+ $contents = $col->getContents($row1);
+ $this->assertSame(5, $col->getRowIndex());
+ $this->assertSame(3, $col->getColumnIndex());
+
+ }
+
+ public function test_renders_correctly(): void
+ {
+ $rows = $this->basicTable->getRows();
+ $row1 = $rows->first();
+ $col = IncrementColumn::make('#')->setRowIndex(1);
+ $contents = $col->getContents($row1);
+ $this->assertSame(1, $col->getRowIndex());
+
+ }
+}
diff --git a/tests/views/layouts/app.blade.php b/tests/views/layouts/app.blade.php
new file mode 100644
index 000000000..281164c7f
--- /dev/null
+++ b/tests/views/layouts/app.blade.php
@@ -0,0 +1,13 @@
+
+
+
+
+
+ Laravel Testing Layout
+
+ {{ $slot }}
+
+
+
+
+