Skip to content

Commit cb4dffd

Browse files
committed
feat: add Filament v5 / Livewire v4 compatibility
- Bump filament/filament to ^5.0 and ssd-for-laravel to ^0.2 - Update CI matrix: PHP 8.2-8.4, Laravel 12, drop Laravel 10 - Rewrite tests as unit tests (12 tests, 49 assertions) - Add migration guide v4 -> v5 in README Closes #22
1 parent 16fe4c2 commit cb4dffd

File tree

8 files changed

+176
-65
lines changed

8 files changed

+176
-65
lines changed

.github/workflows/phpstan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
- name: Setup PHP
1717
uses: shivammathur/setup-php@v2
1818
with:
19-
php-version: '8.2'
19+
php-version: '8.4'
2020
coverage: none
2121

2222
- name: Install composer dependencies

.github/workflows/run-tests.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ jobs:
1313
fail-fast: true
1414
matrix:
1515
os: [ubuntu-latest, windows-latest]
16-
php: [8.2, 8.3]
17-
laravel: [10.*, 11.*]
16+
php: [8.2, 8.3, 8.4]
17+
laravel: [12.*]
1818
stability: [prefer-lowest, prefer-stable]
1919
include:
20-
- laravel: [10.*, 11.*]
21-
testbench: 8.*
22-
carbon: 2.*
20+
- laravel: 12.*
21+
testbench: 10.*
22+
carbon: 3.*
2323

2424
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
2525

AGENTS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
> Project map for AI agents. Keep this file up-to-date as the project evolves.
44
55
## Project Overview
6-
Filament v4 plugin for Laravel that provides a `JsonColumn` table column for displaying JSON data as tree or table views in drawers, modals, or inline containers.
6+
Filament v5 plugin for Laravel that provides a `JsonColumn` table column for displaying JSON data as tree or table views in drawers, modals, or inline containers.
77

88
## Tech Stack
99
- **Language:** PHP 8.2+
1010
- **Framework:** Laravel (package via spatie/laravel-package-tools)
11-
- **UI Framework:** Filament v4
11+
- **UI Framework:** Filament v5
1212
- **DTO Base:** pepperfm/ssd-for-laravel
13-
- **Testing:** Pest v3 with Livewire plugin, Orchestra Testbench
13+
- **Testing:** Pest v4 with Livewire plugin, Orchestra Testbench
1414
- **Static Analysis:** PHPStan / Larastan
1515
- **Code Style:** Laravel Pint + PHP CS Fixer
1616

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 5.0.0 - 2026-03-16
4+
5+
### Filament v5 / Livewire v4 compatibility
6+
7+
- Bumped `filament/filament` to `^5.0` (Livewire v4 support)
8+
- Bumped `pepperfm/ssd-for-laravel` to `^0.2`
9+
- Updated CI matrix: added PHP 8.4, Laravel 12, dropped Laravel 10
10+
- No breaking API changes — all existing `JsonColumn` configuration works as-is
11+
312
## 2.0.0 - 22-03-2025
413

514
### Added feature to display nested data with maxDepth = 2

README.md

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# Filament JSON Column (v4)
1+
# Filament JSON Column (v5)
22

33
[![Latest Version on Packagist](https://img.shields.io/packagist/v/pepperfm/filament-json.svg?style=flat-square)](https://packagist.org/packages/pepperfm/filament-json)
44
[![Tests](https://img.shields.io/github/actions/workflow/status/pepperfm/filament-json/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/pepperfm/filament-json/actions?query=workflow%3Arun-tests+branch%3Amain)
55
[![Code Style](https://img.shields.io/github/actions/workflow/status/pepperfm/filament-json/fix-php-code-styling.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/pepperfm/filament-json/actions?query=workflow%3A%22Fix+PHP+code+styling%22+branch%3Amain)
66
[![Downloads](https://img.shields.io/packagist/dt/pepperfm/filament-json.svg?style=flat-square)](https://packagist.org/packages/pepperfm/filament-json)
77

8-
Beautiful JSON viewer column for **Filament v4** tables.
8+
Beautiful JSON viewer column for **Filament v5** tables.
99

1010
- **Render modes:** Tree / Table
1111
- **Presentation modes:** Inline / Modal / Drawer
@@ -20,13 +20,13 @@ Beautiful JSON viewer column for **Filament v4** tables.
2020
### [Documentation on my doc. website](https://docs.pepperfm.com/filament-json)
2121

2222
```bash
23-
composer require pepperfm/filament-json:^4.0
23+
composer r pepperfm/filament-json:^5.0
2424
```
2525

2626
> Previous major versions:
2727
>
28-
> - Filament 4 → `composer require pepperfm/filament-json:^3.0`
29-
> - Filament 3 → `composer require pepperfm/filament-json:^2.0`
28+
> - Filament 4 → `composer r pepperfm/filament-json:^4.0` or `^3.0`
29+
> - Filament 3 → `composer r pepperfm/filament-json:^2.0`
3030
3131
Optionally publish config or views if you want to customize them:
3232

@@ -135,6 +135,23 @@ JsonColumn::make('properties')
135135

136136
---
137137

138+
## Migration from v4 → v5
139+
140+
Filament v5 has no breaking API changes — it adds Livewire v4 support. The upgrade is straightforward:
141+
142+
```bash
143+
composer require pepperfm/filament-json:^5.0
144+
```
145+
146+
No code changes required. All existing `JsonColumn` configuration works as-is.
147+
148+
**Requirements:**
149+
- PHP 8.2+
150+
- Laravel 11.28+ or 12+
151+
- Filament 5.x
152+
153+
---
154+
138155
## Migration from v3 → v4
139156

140157
### TL;DR
@@ -195,10 +212,11 @@ If you test rendering, switch to Filament v4’s **List** resource page approach
195212

196213
## Version matrix
197214

198-
- Filament **4.x**`pepperfm/filament-json:^4.0` && `pepperfm/filament-json:^3.0`
215+
- Filament **5.x**`pepperfm/filament-json:^5.0`
216+
- Filament **4.x**`pepperfm/filament-json:^4.0` or `^3.0`
199217
- Filament **3.x**`pepperfm/filament-json:^2.0`
200218

201-
Your existing constraints like `^2.x` or `^3.x` will continue to resolve to the proper major — v4 won’t auto-install unless you opt in.
219+
Your existing constraints like `^3.x` or `^4.x` will continue to resolve to the proper major — v5 won’t auto-install unless you opt in.
202220

203221
---
204222

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
],
2222
"require": {
2323
"php": "^8.2",
24-
"filament/filament": "^4.0",
25-
"pepperfm/ssd-for-laravel": "^0.0.8",
24+
"filament/filament": "^5.0",
25+
"pepperfm/ssd-for-laravel": "^0.2",
2626
"spatie/laravel-package-tools": "^1.15.0"
2727
},
2828
"require-dev": {

tests/TestCase.php

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,20 @@
77
use BladeUI\Heroicons\BladeHeroiconsServiceProvider;
88
use BladeUI\Icons\BladeIconsServiceProvider;
99
use Filament\Actions\ActionsServiceProvider;
10-
use Filament\Facades\Filament;
1110
use Filament\FilamentServiceProvider;
1211
use Filament\Forms\FormsServiceProvider;
1312
use Filament\Infolists\InfolistsServiceProvider;
1413
use Filament\Notifications\NotificationsServiceProvider;
15-
use Filament\Panel;
16-
use Filament\PanelRegistry;
1714
use Filament\Support\SupportServiceProvider;
1815
use Filament\Tables\TablesServiceProvider;
1916
use Filament\Widgets\WidgetsServiceProvider;
20-
use Illuminate\Database\Eloquent\Factories\Factory;
2117
use Livewire\LivewireServiceProvider;
2218
use Orchestra\Testbench\TestCase as Orchestra;
2319
use RyanChandler\BladeCaptureDirective\BladeCaptureDirectiveServiceProvider;
2420
use PepperFM\FilamentJson\FilamentJsonServiceProvider;
2521

2622
class TestCase extends Orchestra
2723
{
28-
protected function setUp(): void
29-
{
30-
parent::setUp();
31-
32-
Factory::guessFactoryNamesUsing(
33-
static fn(string $modelName) => 'PepperFM\FilamentJson\Database\Factories\\' . class_basename($modelName) . 'Factory'
34-
);
35-
36-
$panel = Panel::make()
37-
->default()
38-
->id('tests')
39-
->path('tests')
40-
->resources([\PepperFM\FilamentJson\Tests\src\Fixtures\UserResource::class]);
41-
42-
app(PanelRegistry::class)->register($panel);
43-
Filament::setCurrentPanel($panel);
44-
}
45-
4624
protected function getPackageProviders($app): array
4725
{
4826
return [
@@ -59,31 +37,16 @@ protected function getPackageProviders($app): array
5937
TablesServiceProvider::class,
6038
WidgetsServiceProvider::class,
6139
FilamentJsonServiceProvider::class,
62-
63-
\PepperFM\FilamentJson\Tests\src\Fixtures\TestPanelProvider::class,
6440
];
6541
}
6642

67-
protected function defineDatabaseMigrations(): void
68-
{
69-
$this->loadMigrationsFrom(__DIR__ . '/database/migrations');
70-
}
71-
7243
public function getEnvironmentSetUp($app): void
7344
{
74-
// $app['config']->set('session.driver', 'array');
7545
$app['config']->set('database.default', 'testing');
7646
$app['config']->set('database.connections.testing', [
7747
'driver' => 'sqlite',
7848
'database' => ':memory:',
7949
'prefix' => '',
8050
]);
81-
$app['config']->set(
82-
'view.paths',
83-
array_merge(
84-
$app['config']->get('view.paths'),
85-
[__DIR__ . '/resources/views']
86-
)
87-
);
8851
}
8952
}

tests/src/ColumnTest.php

Lines changed: 131 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,137 @@
22

33
declare(strict_types=1);
44

5-
use PepperFM\FilamentJson\Tests\src\Models\User;
5+
use PepperFM\FilamentJson\Columns\JsonColumn;
6+
use PepperFM\FilamentJson\Enums\ContainerModeEnum;
7+
use PepperFM\FilamentJson\Enums\RenderModeEnum;
8+
use PepperFM\FilamentJson\Dto\ButtonConfigDto;
9+
use PepperFM\FilamentJson\Dto\ModalConfigDto;
610

7-
use function Pest\Livewire\livewire;
11+
test('it creates column with default settings', function (): void {
12+
$column = JsonColumn::make('properties');
813

9-
test('can render column', function (): void {
10-
$user = User::factory()->make();
14+
expect($column->getName())->toBe('properties')
15+
->and($column->getRenderMode())->toBe(RenderModeEnum::Tree)
16+
->and($column->getContainerMode())->toBe(ContainerModeEnum::Drawer)
17+
->and($column->getFilterNullable())->toBeTrue()
18+
->and($column->getMaxDepth())->toBe(3)
19+
->and($column->getCharacterLimit())->toBeNull()
20+
->and($column->getInitiallyCollapsed())->toBe(1)
21+
->and($column->getExpandAllToggle())->toBeFalse()
22+
->and($column->getCopyJsonAction())->toBeTrue();
23+
});
1124

12-
livewire(\PepperFM\FilamentJson\Tests\src\Fixtures\ListUsers::class)
13-
->assertSuccessful()
14-
->assertCanRenderTableColumn('properties')
15-
->assertTableColumnExists('properties')
16-
->assertTableColumnStateSet('properties', $user->properties, $user);
17-
})->skip();
25+
test('it sets render mode', function (): void {
26+
$column = JsonColumn::make('data');
27+
28+
$column->renderAs(RenderModeEnum::Table);
29+
expect($column->getRenderMode())->toBe(RenderModeEnum::Table)
30+
->and($column->isTable())->toBeTrue()
31+
->and($column->isTree())->toBeFalse();
32+
33+
$column->asTree();
34+
expect($column->getRenderMode())->toBe(RenderModeEnum::Tree)
35+
->and($column->isTree())->toBeTrue();
36+
37+
$column->asTable();
38+
expect($column->isTable())->toBeTrue();
39+
});
40+
41+
test('it sets container mode', function (): void {
42+
$column = JsonColumn::make('data');
43+
44+
$column->presentIn(ContainerModeEnum::Modal);
45+
expect($column->getContainerMode())->toBe(ContainerModeEnum::Modal)
46+
->and($column->isModalContainer())->toBeTrue()
47+
->and($column->isDrawerContainer())->toBeFalse();
48+
49+
$column->inDrawer();
50+
expect($column->isDrawerContainer())->toBeTrue();
51+
52+
$column->inModal();
53+
expect($column->isModalContainer())->toBeTrue();
54+
55+
$column->inlineContainer();
56+
expect($column->isInlineContainer())->toBeTrue();
57+
});
58+
59+
test('deprecated container methods delegate to new API', function (): void {
60+
$column = JsonColumn::make('data');
61+
62+
$column->asModal();
63+
expect($column->isModalContainer())->toBeTrue()
64+
->and($column->getAsModal())->toBeTrue();
65+
66+
$column->asDrawer();
67+
expect($column->isDrawerContainer())->toBeTrue()
68+
->and($column->getAsDrawer())->toBeTrue();
69+
});
70+
71+
test('it configures UX toggles', function (): void {
72+
$column = JsonColumn::make('data')
73+
->initiallyCollapsed(2)
74+
->expandAllToggle()
75+
->copyJsonAction(false)
76+
->maxDepth(5)
77+
->filterNullable(false)
78+
->characterLimit(100);
79+
80+
expect($column->getInitiallyCollapsed())->toBe(2)
81+
->and($column->getExpandAllToggle())->toBeTrue()
82+
->and($column->getCopyJsonAction())->toBeFalse()
83+
->and($column->getMaxDepth())->toBe(5)
84+
->and($column->getFilterNullable())->toBeFalse()
85+
->and($column->getCharacterLimit())->toBe(100);
86+
});
87+
88+
test('it configures table labels', function (): void {
89+
$column = JsonColumn::make('data')
90+
->keyColumnLabel('Property')
91+
->valueColumnLabel('Data');
92+
93+
expect($column->getKeyColumnLabel())->toBe('Property')
94+
->and($column->getValueColumnLabel())->toBe('Data');
95+
});
96+
97+
test('it applies character limit to strings', function (): void {
98+
$column = JsonColumn::make('data')->characterLimit(10);
99+
100+
expect($column->applyLimit('short'))->toBe('short')
101+
->and($column->applyLimit('this is a very long string'))->toBe('this is a...')
102+
->and($column->applyLimit(null))->toBeNull()
103+
->and($column->applyLimit(['array']))->toBe(['array']);
104+
});
105+
106+
test('it accepts button config', function (): void {
107+
$column = JsonColumn::make('data')
108+
->button(['color' => 'danger', 'label' => 'View']);
109+
110+
$config = $column->getButtonConfig();
111+
112+
expect($config)->toBeInstanceOf(ButtonConfigDto::class)
113+
->and($config->color)->toBe('danger')
114+
->and($config->label)->toBe('View');
115+
});
116+
117+
test('it accepts modal config', function (): void {
118+
$column = JsonColumn::make('data')
119+
->modal(['width' => 'lg', 'closedByEscaping' => false]);
120+
121+
$config = $column->getModalConfig();
122+
123+
expect($config)->toBeInstanceOf(ModalConfigDto::class)
124+
->and($config->width)->toBe('lg')
125+
->and($config->closedByEscaping)->toBeFalse();
126+
});
127+
128+
test('initiallyCollapsed enforces minimum of 0', function (): void {
129+
$column = JsonColumn::make('data')->initiallyCollapsed(-1);
130+
131+
expect($column->getInitiallyCollapsed())->toBe(0);
132+
});
133+
134+
test('maxDepth enforces minimum of 1', function (): void {
135+
$column = JsonColumn::make('data')->maxDepth(0);
136+
137+
expect($column->getMaxDepth())->toBe(1);
138+
});

0 commit comments

Comments
 (0)