Skip to content

Commit 0eadf9d

Browse files
committed
Merge remote-tracking branch 'origin/v4-develop' into CollapseRework5
2 parents 081279e + 74beb4c commit 0eadf9d

28 files changed

+579
-187
lines changed

CHANGELOG.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,27 @@
22

33
All notable changes to `laravel-livewire-tables` will be documented in this file
44

5+
## [v3.7.3] - 2025-05-03
6+
### Bug Fixes
7+
- Interim fix for Livewire Component Columns to mitigate core Livewire bug by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2258
8+
9+
## [v3.7.2] - 2025-05-03
10+
### Bug Fixes
11+
- Improved Pagination UX for Bootstrap 4 by @daniel-skopek in https://github.com/rappasoft/laravel-livewire-tables/pull/2251
12+
- Fixes for livewire component column by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2245
13+
- Boolean filter for bootstrap by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2244
14+
- Update IsNumericFilter.php by @G4Zz0L1 in https://github.com/rappasoft/laravel-livewire-tables/pull/2230
15+
- Fixed collapsed function bug with tailwind CSS on mobile version by CarlosChub27 in https://github.com/rappasoft/laravel-livewire-tables/pull/2228
16+
17+
### New Features
18+
- Add Wrapper Options to ArrayColumn by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2255
19+
20+
### Tweaks
21+
- Tidying PHPDocs by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2246
22+
523
## [v3.7.1] - 2025-02-28
624
### Bug Fixes
7-
- Ensure that LinkColumn is included in query if "from" is defined
25+
- Ensure that LinkColumn is included in query if "from" is defined by @lrljoe in https://github.com/rappasoft/laravel-livewire-tables/pull/2224
826

927
## [v3.7.0] - 2025-02-27
1028

docs/column-types/array_column.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,64 @@ ArrayColumn::make('notes', 'name')
1313
->sortable(),
1414
```
1515

16-
### Empty Value
16+
## Empty Value
1717
You may define the default/empty value using the "emptyValue" method
1818

1919
```php
2020
ArrayColumn::make('notes', 'name')
2121
->emptyValue('Unknown'),
2222
```
2323

24+
## Wrapping the Output
25+
26+
As the ArrayColumn is designed to handle multiple related records, you can choose to wrap these for improved UX.
27+
28+
It is recommended that you utilise the built-in flexCol or flexRow approaches, which will also disable the separator
29+
30+
### flexCol
31+
This adds either:
32+
- Tailwind: 'flex flex-col'
33+
- Bootstrap: 'd-flex d-flex-col'
34+
35+
And merges any attributes specified in the sole parameter (as an array)
36+
```php
37+
ArrayColumn::make('notes', 'name')
38+
->data(fn($value, $row) => ($row->notes))
39+
->outputFormat(fn($index, $value) => "<a href='".$value->id."'>".$value->name."</a>")
40+
->flexCol(['class' => 'bg-red-500'])
41+
->sortable(),
42+
```
43+
44+
### flexRow
45+
46+
This adds either:
47+
- Tailwind: 'flex flex-row'
48+
- Bootstrap: 'd-flex d-flex-row'
49+
50+
And merges any attributes specified in the sole parameter (as an array)
51+
```php
52+
ArrayColumn::make('notes', 'name')
53+
->data(fn($value, $row) => ($row->notes))
54+
->outputFormat(fn($index, $value) => "<a href='".$value->id."'>".$value->name."</a>")
55+
->flexRow(['class' => 'bg-red-500'])
56+
->sortable(),
57+
```
58+
59+
### Manually
60+
61+
You can also specify a wrapperStart and wrapperEnd, for example, for an unordered list:
62+
63+
```php
64+
ArrayColumn::make('notes', 'name')
65+
->data(fn($value, $row) => ($row->notes))
66+
->outputFormat(fn($index, $value) => "<li><a href='".$value->id."'>".$value->name."</a></li>")
67+
->wrapperStart("<ul class='bg-blue'>")
68+
->wrapperEnd("</ul>")
69+
->sortable(),
70+
```
71+
72+
## See Also
73+
2474
Please also see the following for other available methods:
2575
<ul>
2676
<li>

docs/column-types/boolean_columns.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ BooleanColumn::make('Active', 'status')
8989
->toggleable('changeStatus'),
9090
```
9191

92-
Then your "changeStatus" method may look like
92+
Then your "changeStatus" method may look like (make sure you are selecting the `id` in the query)
9393
```php
9494
public function changeStatus(int $id)
9595
{
@@ -108,7 +108,7 @@ BooleanColumn::make('Active', 'status')
108108
->toggleable('changeStatus'),
109109
```
110110

111-
Then your "changeStatus" method may look like
111+
Then your "changeStatus" method may look like (make sure you are selecting the `id` in the query)
112112
```php
113113
public function changeStatus(int $id)
114114
{

docs/filter-types/filters-boolean.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ weight: 2
44
---
55

66
## Beta
7-
This is currently in beta, and will only work with Tailwind.
7+
This is currently in beta, but should work with Tailwind, Bootstrap 4 and Bootstrap 5 as of latest version
88

99
## Details
1010

phpstan.neon

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,25 @@ parameters:
1313
treatPhpDocTypesAsCertain: false
1414
reportUnmatchedIgnoredErrors: false
1515
ignoreErrors:
16-
- identifier: argument.type
17-
- identifier: argument.templateType
18-
- identifier: new.static
16+
- identifier: missingType.generics
17+
- identifier: missingType.iterableValue
18+
- identifier: trait.unused
19+
- identifier: deadCode.unreachable
20+
- identifier: booleanNot.alwaysTrue
21+
paths:
22+
- src/Views/Columns/Traits/HasDataTableComponent.php
23+
- identifier: notIdentical.alwaysTrue
24+
paths:
25+
- src/Traits/Filters/Helpers/FilterPillsHelpers.php
26+
- src/Traits/Helpers/CustomisationsHelpers.php
27+
- src/Traits/Helpers/QueryHelpers.php
28+
- src/Views/Columns/Traits/HasSlot.php
29+
- src/Views/Columns/Traits/Helpers/ArrayColumnHelpers.php
1930
- identifier: function.alreadyNarrowedType
2031
paths:
2132
- src/Views/Filters/MultiSelectDropdownFilter.php
2233
- src/Views/Filters/Traits/HasOptions.php
2334
- src/Views/Traits/Core/HasView.php
24-
- identifier: missingType.generics
25-
paths:
26-
- src/Traits/WithData.php
27-
- identifier: empty.offset
28-
paths:
29-
- src/Traits/Filters/Helpers/FilterMenuHelpers.php
30-
- identifier: isset.offset
35+
- identifier: unset.possiblyHookedProperty
3136
paths:
32-
- src/Traits/Filters/Helpers/FilterMenuHelpers.php
33-
- message: '# \$view of function view expects view-string\|null, string given.#'
37+
- src/Traits/Configuration/CollapsingColumnConfiguration.php
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
@aware([ 'tableName', 'primaryKey','isTailwind','isBootstrap'])
2+
@props(['row', 'rowIndex'])
3+
4+
@if ($this->collapsingColumnsAreEnabled && $this->hasCollapsedColumns)
5+
@php($customAttributes = $this->getTrAttributes($row, $rowIndex))
6+
<tr x-data
7+
@toggle-row-content.window="($event.detail.tableName === '{{ $tableName }}' && $event.detail.row === {{ $rowIndex }}) ? $el.classList.toggle('{{ $isBootstrap ? 'd-none' : 'hidden' }}') : null"
8+
{{
9+
$attributes->merge([
10+
'wire:loading.class.delay' => 'opacity-50 dark:bg-gray-900 dark:opacity-60',
11+
'wire:key' => $tableName.'-row-'.$row->{$primaryKey}.'-collapsed-contents',
12+
])
13+
->merge($customAttributes)
14+
->class([
15+
'hidden bg-white dark:bg-gray-700 dark:text-white rappasoft-striped-row' => ($isTailwind && ($customAttributes['default'] ?? true) && $rowIndex % 2 === 0),
16+
'hidden bg-gray-50 dark:bg-gray-800 dark:text-white rappasoft-striped-row' => ($isTailwind && ($customAttributes['default'] ?? true) && $rowIndex % 2 !== 0),
17+
'd-none bg-light rappasoft-striped-row' => ($isBootstrap && $rowIndex % 2 === 0 && ($customAttributes['default'] ?? true)),
18+
'd-none bg-white rappasoft-striped-row' => ($isBootstrap && $rowIndex % 2 !== 0 && ($customAttributes['default'] ?? true)),
19+
])
20+
->except(['default','default-styling','default-colors'])
21+
}}
22+
>
23+
<td colspan="{{ $this->getColspanCount }}" @class([
24+
'text-left pt-4 pb-2 px-4' => $isTailwind,
25+
'text-start pt-3 p-2' => $isBootstrap,
26+
])>
27+
<div>
28+
@foreach($this->getCollapsedColumnsForContent as $colIndex => $column)
29+
30+
<p wire:key="{{ $tableName }}-row-{{ $row->{$primaryKey} }}-collapsed-contents-{{ $colIndex }}" @class([
31+
'block mb-2' => $isTailwind,
32+
'sm:block' => $isTailwind && $column->shouldCollapseAlways(),
33+
'sm:block md:hidden' => $isTailwind && !$column->shouldCollapseAlways() && !$column->shouldCollapseOnTablet() && $column->shouldCollapseOnMobile(),
34+
'sm:block lg:hidden' => $isTailwind && !$column->shouldCollapseAlways() && ($column->shouldCollapseOnTablet() || $column->shouldCollapseOnMobile()),
35+
36+
'd-block mb-2' => $isBootstrap,
37+
'd-sm-none' => $isBootstrap && !$column->shouldCollapseAlways() && !$column->shouldCollapseOnTablet() && !$column->shouldCollapseOnMobile(),
38+
'd-md-none' => $isBootstrap && !$column->shouldCollapseAlways() && !$column->shouldCollapseOnTablet() && $column->shouldCollapseOnMobile(),
39+
'd-lg-none' => $isBootstrap && !$column->shouldCollapseAlways() && ($column->shouldCollapseOnTablet() || $column->shouldCollapseOnMobile()),
40+
])>
41+
<strong>{{ $column->getTitle() }}</strong>:
42+
@if($column->isHtml())
43+
{!! $column->setIndexes($rowIndex, $colIndex)->renderContents($row) !!}
44+
@else
45+
{{ $column->setIndexes($rowIndex, $colIndex)->renderContents($row) }}
46+
@endif
47+
</p>
48+
@endforeach
49+
</div>
50+
</td>
51+
</tr>
52+
@endif

resources/views/components/tools/filters/boolean.blade.php

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,38 @@
22
$defaultValue = ($filter->hasFilterDefaultValue() ? (bool) $filter->getFilterDefaultValue() : false)
33
@endphp
44
@if($isTailwind)
5-
<div class="flex flex-cols"
6-
x-data="newBooleanFilter($wire, '{{ $filter->getKey() }}', '{{ $tableName }}', '{{ $defaultValue }}')"
7-
>
8-
<x-livewire-tables::tools.filter-label :$filter :$filterLayout :$tableName :$isTailwind :$isTailwind4 :$isBootstrap4 :$isBootstrap5 :$isBootstrap />
9-
<input id="thisId" type="checkbox" name="switch" class="hidden" :checked="value" />
5+
<div class="flex flex-cols" x-data="newBooleanFilter('{{ $filter->getKey() }}', '{{ $tableName }}', '{{ $defaultValue }}')">
6+
<x-livewire-tables::tools.filter-label :$filter :$filterLayout :$tableName :$isTailwind :$isBootstrap4 :$isBootstrap5 :$isBootstrap />
7+
<input id="thisId" type="checkbox" name="switch" class="hidden" :checked="value" />
108

11-
<button x-cloak {{ $filterInputAttributes->merge([
12-
":class" => "(value == 1 || value == true) ? '".$filterInputAttributes['activeColor']."' : '".$filterInputAttributes['inactiveColor']."'",
13-
])
14-
->class([
15-
'relative inline-flex h-6 py-0.5 ml-4 focus:outline-none rounded-full w-10' => $isTailwind && ($filterInputAttributes['default-styling'] ?? true),
16-
'tw4ph relative inline-flex h-6 py-0.5 ml-4 focus:outline-none rounded-full w-10' => $isTailwind4 && ($filterInputAttributes['default-styling'] ?? true),
17-
])
18-
->except(['default-styling','default-colors','activeColor','inactiveColor','blobColor'])
19-
}}>
20-
<span :class="(value == 1 || value == true) ? 'translate-x-[18px]' : 'translate-x-0.5'"
21-
@class([
22-
$filterInputAttributes['blobColor'],
23-
'w-5 h-5 duration-200 ease-in-out rounded-full shadow-md' => $isTailwind,
24-
'tw4ph w-5 h-5 duration-200 ease-in-out rounded-full shadow-md' => $isTailwind4,
25-
])>
26-
</span>
27-
</button>
28-
<template x-if="(value == 1 || value == true)">
29-
<button @click="toggleStatusWithReset" type="button"
30-
@class([
31-
'flex-shrink-0 ml-1 h-6 w-6 rounded-full inline-flex items-center justify-center text-indigo-400 hover:bg-indigo-200 hover:text-indigo-500 focus:outline-none focus:bg-indigo-500 focus:text-white' => $isTailwind,
32-
'tw4ph flex-shrink-0 ml-1 h-6 w-6 rounded-full inline-flex items-center justify-center text-indigo-400 hover:bg-indigo-200 hover:text-indigo-500 focus:outline-none focus:bg-indigo-500 focus:text-white' => $isTailwind4,
33-
])
34-
>
35-
36-
<span class="sr-only">{{ __($localisationPath.'Remove filter option') }}</span>
37-
<x-heroicon-m-x-mark class="h-6 w-6" />
9+
<button x-cloak {{ $filterInputAttributes->merge([
10+
":class" => "(value == 1 || value == true) ? '".$filterInputAttributes['activeColor']."' : '".$filterInputAttributes['inactiveColor']."'",
11+
])
12+
->class([
13+
'relative inline-flex h-6 py-0.5 ml-4 focus:outline-none rounded-full w-10' => ($filterInputAttributes['default-styling'] ?? true)
14+
])
15+
->except(['default-styling','default-colors','activeColor','inactiveColor','blobColor'])
16+
}}>
17+
<span :class="(value == 1 || value == true) ? 'translate-x-[18px]' : 'translate-x-0.5'" class="w-5 h-5 duration-200 ease-in-out rounded-full shadow-md {{ $filterInputAttributes['blobColor'] }}"></span>
3818
</button>
39-
</template>
40-
</div>
41-
@else
42-
<div class="form-check form-switch"
43-
x-data="newBooleanFilter('{{ $filter->getKey() }}', '{{ $tableName }}', '{{ $defaultValue }}')"
44-
>
45-
<x-livewire-tables::tools.filter-label :$filter :$filterLayout :$tableName :$isTailwind :$isBootstrap4 :$isBootstrap5 :$isBootstrap />
46-
<input id="thisId" type="checkbox" name="switch" class="form-check-input" role="switch" :checked="value" @click="toggleStatusWithUpdate" x-ref="switchButton"/>
47-
19+
<template x-if="(value == 1 || value == true)">
20+
<button @click="toggleStatusWithReset" type="button"
21+
class="flex-shrink-0 ml-1 h-6 w-6 rounded-full inline-flex items-center justify-center text-indigo-400 hover:bg-indigo-200 hover:text-indigo-500 focus:outline-none focus:bg-indigo-500 focus:text-white"
22+
>
4823

24+
<span class="sr-only">{{ __($localisationPath.'Remove filter option') }}</span>
25+
<x-heroicon-m-x-mark class="h-6 w-6" />
26+
</button>
27+
</template>
28+
</div>
29+
@elseif($isBootstrap4)
30+
<div class="custom-control custom-switch" x-data="newBooleanFilter('{{ $filter->getKey() }}', '{{ $tableName }}', '{{ $defaultValue }}')">
31+
<input type="checkbox" class="custom-control-input" id="customSwitch1" :checked="value" @click="toggleStatusWithUpdate" x-ref="switchButton">
32+
<x-livewire-tables::tools.filter-label class="custom-control-label" for="customSwitch1" :$filter :$filterLayout :$tableName :$isTailwind :$isBootstrap4 :$isBootstrap5 :$isBootstrap />
33+
</div>
34+
@else
35+
<div class="form-check form-switch" x-data="newBooleanFilter('{{ $filter->getKey() }}', '{{ $tableName }}', '{{ $defaultValue }}')">
36+
<x-livewire-tables::tools.filter-label :$filter :$filterLayout :$tableName :$isTailwind :$isBootstrap4 :$isBootstrap5 :$isBootstrap />
37+
<input id="thisId" type="checkbox" name="switch" class="form-check-input" role="switch" :checked="value" @click="toggleStatusWithUpdate" x-ref="switchButton"/>
4938
</div>
5039
@endif

resources/views/specific/bootstrap-4/pagination.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
@php(isset($this->numberOfPaginatorsRendered[$paginator->getPageName()]) ? $this->numberOfPaginatorsRendered[$paginator->getPageName()]++ : $this->numberOfPaginatorsRendered[$paginator->getPageName()] = 1)
44

55
<nav>
6-
<ul class="pagination">
6+
<ul class="pagination d-flex flex-wrap justify-content-start">
77
{{-- Previous Page Link --}}
88
@if ($paginator->onFirstPage())
99
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">

src/DataTransferObjects/DebuggableData.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,10 @@
66

77
class DebuggableData
88
{
9-
public DataTableComponent $component;
10-
11-
public function __construct(DataTableComponent $component)
12-
{
13-
$this->component = $component;
14-
}
9+
public function __construct(public DataTableComponent $component) {}
1510

1611
/**
17-
* Undocumented function
12+
* Returns data to an array
1813
*
1914
* @return array<mixed>
2015
*/

src/DataTransferObjects/FilterGenericData.php

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,10 @@
44

55
class FilterGenericData
66
{
7-
public string $tableName;
8-
9-
public string $filterLayout;
10-
11-
public bool $isTailwind = false;
12-
13-
public bool $isTailwind4 = false;
14-
15-
public bool $isBootstrap4 = false;
16-
17-
public bool $isBootstrap5 = false;
18-
19-
public function __construct(string $tableName, string $filterLayout, bool $isTailwind = false, bool $isBootstrap4 = false, bool $isBootstrap5 = false, bool $isTailwind4 = false)
20-
{
21-
$this->tableName = $tableName;
22-
$this->filterLayout = $filterLayout;
23-
$this->isTailwind = $isTailwind;
24-
$this->isTailwind4 = $isTailwind4;
25-
$this->isBootstrap4 = $isBootstrap4;
26-
$this->isBootstrap5 = $isBootstrap5;
27-
}
7+
public function __construct(public string $tableName, public string $filterLayout, public bool $isTailwind = false, public bool $isBootstrap4 = false, public bool $isBootstrap5 = false) {}
288

299
/**
30-
* Undocumented function
10+
* Convert To Array
3111
*
3212
* @return array<mixed>
3313
*/

0 commit comments

Comments
 (0)